I'm trying to communicate with some test equipment from C# over SCPI. I managed to communicate with one device that is connected through TCP/IP by using this code example.
However, my other devices are connected through USB and I haven't find how to communicate with them over USB.
BTW, I found this question, and the link from the answer to the IVI-COM programming examples in C# document, but I couldn't apply the code samples (e.g. in section 5.4) because all of the IVI and VISA COM libraries I found (e.g. VisaComLib 5.5) has only interfaces and enums in it, and no concrete class that I can use...
If you install the visa driver from either NationalInstruments or Keysight, they do implement classes:
The one from NI:
FormattedIO488Class
ResourceManagerClass
VisaConflictTableManagerClass
To get a connection, you only need 1 and 2
As soon as you try to embed the interoptypes, you need to remove the 'Class' suffix, as described here
Here comes a sample snippet from Keysight (Application Note: 5989-6338EN)
Ivi.Visa.Interop.ResourceManager rm = new Ivi.Visa.Interop.ResourceManager();
Ivi.Visa.Interop.FormattedIO488 ioobj = new Ivi.Visa.Interop.FormattedIO488();
try
{
object[] idnItems;
ioobj.IO = (Ivi.Visa.Interop.IMessage)rm.Open("GPIB2::10::INSTR",
Ivi.Visa.Interop.AccessMode.NO_LOCK, 0, "");
ioobj.WriteString("*IDN ?", true);
idnItems = (object[])ioobj.ReadList(Ivi.Visa.Interop.IEEEASCIIType.ASCIIType_Any, ",");
foreach(object idnItem in idnItems)
{
System.Console.Out.WriteLine("IDN Item of type " + idnItem.GetType().ToString());
System.Console.Out.WriteLine("\tValue of item is " + idnItem.ToString());
}
}
catch(Exception e)
{
System.Console.Out.WriteLine("An error occurred: " + e.Message);
}
finally
{
try { ioobj.IO.Close(); }
catch { }
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(ioobj);
}
catch { }
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(rm);
}
catch { }
}
I'm using National Instruments VISA.
Add a reference to NationalInstruments.VisaNS and NationalInstruments.Common to your project.
Create a MessageBasedSession, see the following code:
string resourceName = "USB0::0x0957::0x0118::US56070667::INSTR"; // See NI MAX for resource name
var visa = new NationalInstruments.VisaNS.MessageBasedSession(resourceName);
visa.Write("*IDN?"); // write to instrument
string res = visa.ReadString(); // read from instrument
See as well https://stackoverflow.com/a/49388678/7556646.
Related
I'm trying to write a C# console app that can programmatically update an Outlook distribution list (DL) in the Global Address List (GAL). I have permission to update this DL. I can do it interactively on my PC using Outlook, and I can do it in Perl code using Win32::NetAdmin::GroupAddUsers.
After adding a reference to COM library "Microsoft Outlook 14.0 Object Library", and then accessed via:
using Outlook = Microsoft.Office.Interop.Outlook;
I can successfully read from a DL, even recursing through DL's inside the "main" DL being searched. Here's that working code (critiques not needed for this piece):
private static List<Outlook.AddressEntry> GetMembers(string dl, bool recursive)
{
try
{
List<Outlook.AddressEntry> memberList = new List<Outlook.AddressEntry>();
Outlook.Application oApp = new Outlook.Application();
Outlook.AddressEntry dlEntry = oApp.GetNamespace("MAPI").AddressLists["Global Address List"].AddressEntries[dl];
if (dlEntry.Name == dl)
{
Outlook.AddressEntries members = dlEntry.Members;
foreach (Outlook.AddressEntry member in members)
{
if (recursive && (member.AddressEntryUserType == Outlook.OlAddressEntryUserType.olExchangeDistributionListAddressEntry))
{
List<Outlook.AddressEntry> sublist = GetMembers(member.Name, true);
foreach (Outlook.AddressEntry submember in sublist)
{
memberList.Add(submember);
}
}
else {
memberList.Add(member);
}
}
}
else
{
Console.WriteLine("Could not find an exact match for '" + dl + "'.");
Console.WriteLine("Closest match was '" + dlEntry.Name +"'.");
}
return memberList;
}
catch
{
// This mostly fails if running on a PC without Outlook.
// Return a null, and require the calling code to handle it properl
// (or that code will get a null-reference excception).
return null;
}
}
I can use the output of that to examine the members closely, so I think I understand the DL/member objects a bit.
But, the following code will NOT add a member to a DL:
private static void AddMembers(string dl)
{
Outlook.Application oApp = new Outlook.Application();
Outlook.AddressEntry ae = oApp.GetNamespace("MAPI").AddressLists["Global Address List"].AddressEntries[dl];
try {
ae.Members.Add("EX", "Tuttle, James", "/o=EMC/ou=North America/cn=Recipients/cn=tuttlj");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
ae.Update();
}
The arguments to Members.Add() are defined here, and the values shown in my code come exactly from examining my own Member object from another DL.
The exception displayed is simply "The bookmark is not valid." A similar question was asked before, but the solution was to use P/Invoke or LDAP. I really have no idea how to use P/Invoke (strictly a C# and Perl programmer, not a Windows/C/C++ programmer), and I don't have access to the LDAP server, so I really want to get this working through the Microsoft.Office.Interop.Outlook objects.
Any help is GREATLY appreciated!
After experimenting with several different .NET objects, using System.DirectorServices.AccountManagement as posted in Adding and removing users from Active Directory groups in .NET is what finally code this working for me. Closing out my own question.
I have a ClickOnce Publish Name that is different from the assembly name. For discussion purposes, it is "App 6.0". I set it in the Properties for my project. Is there any way to get this value from inside the program?
Add a reference to Microsoft.Build.Tasks.v4.0.dll, then run this:
if (null != AppDomain.CurrentDomain.ActivationContext)
{
DeployManifest manifest;
using (MemoryStream stream = new MemoryStream(AppDomain.CurrentDomain.ActivationContext.DeploymentManifestBytes))
{
manifest = (DeployManifest)ManifestReader.ReadManifest("Deployment", stream, true);
}
// manifest.Product has the name you want
}
else
{
// not deployed
}
The DeployManifest can also provide other useful info from your manifest, like Publisher or SupportUrl.
The answer can be found in ClickOnce Run at Startup. Essentially, you use InPlaceHostingManager to get the ClickOnce manifest and read it. It bugs me that it is an asynchronous method, but this is the only thing that has worked thus far. Simplifications are much appreciated. See the webpage for a description of DeploymentDescription.
var inPlaceHostingManager = new InPlaceHostingManager(ApplicationDeployment.CurrentDeployment.UpdateLocation, false);
inPlaceHostingManager.GetManifestCompleted += ((sender, e) =>
{
try
{
var deploymentDescription = new DeploymentDescription(e.DeploymentManifest);
string productName = deploymentDescription.Product;
***DoSomethingToYour(productName);***
// - use this later -
//var commandBuilder = new StartMenuCommandBuilder(deploymentDescription);
//string startMenuCommand = commandBuilder.Command;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
}
});
ApplicationDeployment.UpdatedApplicationFullName Property
I have below java code , I need to convert these in C#, Kindly help me ..
public class Configuration {
private ConfigContentHandler confHandler;
public Configuration() {
}
public boolean parseConfigFile() throws Exception {
boolean bReturn = true;
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
System.out.println("*** Start parsing");
try {
confHandler = new ConfigContentHandler(100);
// Configuration file must be located in main jar file folder
// Set the full Prosper file name
String sConfigFile = "configuration.xml";
// Get abstract (system independent) filename
File fFile = new File(sConfigFile);
if (!fFile.exists()) {
System.out.println("Could not find configuration file " + sConfigFile + ", trying input parameters.");
bReturn = false;
} else if (!fFile.canRead()) {
System.out.println("Could not read configuration file " + sConfigFile + ", trying input parameters.");
bReturn = false;
} else {
parser.parse(fFile, confHandler);
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Input error.");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("*** End parsing");
return bReturn;
}
Thanks
C# native XML parser XmlReader doesn't support SAX and is forward-only. You may take a look at this article presenting some specific points about it. You could simulate a SAX parser using XmlReader. If it doesn't suit your needs you could also use XDocument which is a different API for working with XML files in .NET. So to conclude there's no push XML parser built into .NET framework so you might need to use a third party library or COM Interop to MSXML to achieve this if you really need an event driven parser.
I used SAX for .NET in two projects successfully in the past.
http://saxdotnet.sourceforge.net/
Iv'e recently started a new job as an ICT Technician and im creating an Console application which will consists of stuff that will help our daily tools!
My first tool is a Network Scanner, Our system currently runs on Vanilla and Asset tags but the only way we can find the hostname / ip address is by going into the Windows Console tools and nslookup which to me can be improved
I want to create an application in which I enter a 6 digit number and the application will search the whole DNS for a possible match!
Our hostsnames are like so
ICTLN-D006609-edw.srv.internal the d 006609 would be the asset tag for that computer.
I wish to enter that into the Console Application and it search through every hostname and the ones that contain the entered asset tag within the string will be returned along with an ip and full computer name ready for VNC / Remote Desktop.
Firstly how would I go about building this, shall i start the project of as a console app or a WPF. can you provide an example of how I can scan the hostnames via C#, or if there's an opensource C# version can you provide a link.
Any information would be a great help as it will take out alot of issues in the workpalce as we have to ask the customer to go into there My Computer adn properties etc and then read the Computer name back to use which I find pointless.
Regards.
Updates:
*1 C# Version I made: http://pastebin.com/wBWxyyuh
I would actually go about this with PowerShell, since automating tasks is kinda its thing. In fact, here's a PowerShell script to list out all computers visible on the network. This is easily translatable into C# if you really want it there instead.
function Find-Computer( [string]$assetTag ) {
$searcher = New-Object System.DirectoryServices.DirectorySearcher;
$searcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry;
$searcher.SearchScope = 'Subtree';
$searcher.PageSize = 1000;
$searcher.Filter = '(objectCategory=computer)';
$results = $searcher.FindAll();
$computers = #();
foreach($result in $results) {
$computers += $result.GetDirectoryEntry();
}
$results.Dispose(); #Explicitly needed to free resources.
$computers |? { $_.Name -match $assetTag }
}
Here's a way you can accomplish this, although it's not the best. You might consider hitting Active Directory to find the legitimate machines on your network. The code below shows how you might resolve a machine name, and shows how to ping it:
static void Main()
{
for (int index = 0; index < 999999; index++)
{
string computerName = string.Format("ICTLN-D{0:000000}-edw.srv.internal", index);
string fqdn = computerName;
try
{
fqdn = Dns.GetHostEntry(computerName).HostName;
}
catch (SocketException exception)
{
Console.WriteLine(">>Computer not found: " + computerName + " - " + exception.Message);
}
using (Ping ping = new Ping())
{
PingReply reply = ping.Send(fqdn);
if (reply.Status == IPStatus.Success)
{
Console.WriteLine(">>Computer is alive: " + computerName);
}
else
{
Console.WriteLine(">>Computer did not respond to ping: " + computerName);
}
}
}
}
Hope that helps...
Is there a toolkit/package that is available that I could use to find a list of wireless networks (SSID's) that are available in either Java, C#, or C for Windows XP+? Any sample code would be appreciated.
For C#, take a look at the Managed Wifi API, which is a wrapper for the Native Wifi API provided with Windows XP SP2 and later.
I have not tested this code, but looking at the Managed Wifi API sample code, this should list the available SSIDs.
WlanClient client = new WlanClient();
foreach ( WlanClient.WlanInterface wlanIface in client.Interfaces )
{
// Lists all available networks
Wlan.WlanAvailableNetwork[] networks = wlanIface.GetAvailableNetworkList( 0 );
foreach ( Wlan.WlanAvailableNetwork network in networks )
{
Console.WriteLine( "Found network with SSID {0}.", GetStringForSSID(network.dot11Ssid));
}
}
static string GetStringForSSID(Wlan.Dot11Ssid ssid)
{
return Encoding.ASCII.GetString( ssid.SSID, 0, (int) ssid.SSIDLength );
}
ArrayList<String>ssids=new ArrayList<String>();
ArrayList<String>signals=new ArrayList<String>();
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", "netsh wlan show all");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line.contains("SSID")||line.contains("Signal")){
if(!line.contains("BSSID"))
if(line.contains("SSID")&&!line.contains("name")&&!line.contains("SSIDs"))
{
line=line.substring(8);
ssids.add(line);
}
if(line.contains("Signal"))
{
line=line.substring(30);
signals.add(line);
}
if(signals.size()==7)
{
break;
}
}
}
for (int i=1;i<ssids.size();i++)
{
System.out.println("SSID name == "+ssids.get(i)+" and its signal == "+signals.get(i) );
}
Well, you didn't specify the OS so, for Linux I will suggest Wireless Tools for Linux by Jean Tourrilhes (http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html). The iwlist() command displays a lot of information about the available networks. The source code is in C. Another way is to write your own code in C using libpcap for capturing the beacon frames and extracting SSID from them (in monitor mode only). I haven't tested my sniffing code yet so I won't paste it here but it is pretty simple job.