I have connected customer Display with POS application. I am using serial port class for display message on customer Display. To message I need to know with com port this USB display are using. I have searched allowed there are many examples for getting all com pot for that computer but I am able to find any help to get particular com port no e.g COM93,COM01 or COM2.
I have tried following program and also I have tried Microsoft program WMI code creator.
// Get a list of serial port names.
string[] ports = SerialPort.GetPortNames();
Console.WriteLine("The following serial ports were found:");
// Display each port name to the console.
foreach (string port in ports)
{
Console.WriteLine(port);
}
Console.ReadLine();
SerialPort sp = new SerialPort();
sp.PortName = "COM93";------------- How i can find this no automatic
sp.BaudRate = 9600;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.Open();
sp.Write("\f");
sp.WriteLine("***Velkommen***");
sp.Close();
sp.Dispose();
sp = null;
I have tried following solution as well, to use this as well for this I get access denied so I need to edit registory to give rights that I dot wana do I want solution programmatically
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI", "SELECT * FROM MSSerial_PortName");
public string Get_RegistryInfo(string VID, string PID)
{
try
{
RegistryKey rk1 = Registry.LocalMachine;
// HKEY_LOCAL_MACHINE
RegistryKey rk2 = rk1.OpenSubKey("HARDWARE\\\\DEVICEMAP\\\\SERIALCOMM");
// HKEY_LOCAL_MACHINE\HARDWARE\\\\DEVICEMAP\\\\SERIALCOMM
VendorID = VID;
ProduktID = PID;
string pattern = string.Format("^VID_{0}.PID_{1}", VID, PID);
Regex _rx = new Regex(pattern, RegexOptions.IgnoreCase);
string rk2_SubKeyNames = null;
foreach (string rk2_SubKeyNames_loopVariable in rk2.GetValueNames())
{
rk2_SubKeyNames = rk2_SubKeyNames_loopVariable;
if (rk2_SubKeyNames == "\\Device\\ProlificSerial0")
{
COM_Port = rk2.GetValue(rk2_SubKeyNames).ToString();
}
}
return COM_Port;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return COM_Port;
}
}
Related
I found this code on an old thread to shutdown the local machine:
using System.Management;
void Shutdown()
{
ManagementBaseObject mboShutdown = null;
ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem");
mcWin32.Get();
// You can't shutdown without security privileges
mcWin32.Scope.Options.EnablePrivileges = true;
ManagementBaseObject mboShutdownParams =
mcWin32.GetMethodParameters("Win32Shutdown");
// Flag 1 means we want to shut down the system. Use "2" to reboot.
mboShutdownParams["Flags"] = "1";
mboShutdownParams["Reserved"] = "0";
foreach (ManagementObject manObj in mcWin32.GetInstances())
{
mboShutdown = manObj.InvokeMethod("Win32Shutdown",
mboShutdownParams, null);
}
}
Is it possible to use a similar WMI method to reboot flag "2" a remote machine, for which i only have machine name, not IPaddress.
EDIT: I currently have:
SearchResultCollection allMachinesCollected = machineSearch.FindAll();
Methods myMethods = new Methods();
string pcName;
ArrayList allComputers = new ArrayList();
foreach (SearchResult oneMachine in allMachinesCollected)
{
//pcName = oneMachine.Properties.PropertyNames.ToString();
pcName = oneMachine.Properties["name"][0].ToString();
allComputers.Add(pcName);
MessageBox.Show(pcName + "has been sent the restart command.");
Process.Start("shutdown.exe", "-r -f -t 0 -m \\" + pcName);
}
but this doesn't work, and I would prefer WMI going forward.
To address WMI queries to a remote computer, you simply specify that computer's name (or IP address) in the ManagementScope object.
I'm not well up in C#, but here's an example I came up with using MSDN and WMI Code Creator (which is, by the way, an excellent tool for generating WMI code, and supports C# among others). Hope this code will give you the idea.
(Disclaimer: This code is untested.)
using System;
using System.Management;
...
void Shutdown()
{
try
{
const string computerName = "COMPUTER"; // computer name or IP address
ConnectionOptions options = new ConnectionOptions();
options.EnablePrivileges = true;
// To connect to the remote computer using a different account, specify these values:
// options.Username = "USERNAME";
// options.Password = "PASSWORD";
// options.Authority = "ntlmdomain:DOMAIN";
ManagementScope scope = new ManagementScope(
"\\\\" + computerName + "\\root\\CIMV2", options);
scope.Connect();
SelectQuery query = new SelectQuery("Win32_OperatingSystem");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope, query);
foreach (ManagementObject os in searcher.Get())
{
// Obtain in-parameters for the method
ManagementBaseObject inParams =
os.GetMethodParameters("Win32Shutdown");
// Add the input parameters.
inParams["Flags"] = 2;
// Execute the method and obtain the return values.
ManagementBaseObject outParams =
os.InvokeMethod("Win32Shutdown", inParams, null);
}
}
catch(ManagementException err)
{
MessageBox.Show("An error occurred while trying to execute the WMI method: " + err.Message);
}
catch(System.UnauthorizedAccessException unauthorizedErr)
{
MessageBox.Show("Connection error (user name or password might be incorrect): " + unauthorizedErr.Message);
}
}
I had trouble with this also. WMI can be misleading with methods for classes and object. My solution is for rebooting a host on the network with C# and WMI, but is easily simplified for local machine:
private void rebootHost(string hostName)
{
string adsiPath = string.Format(#"\\{0}\root\cimv2", hostName);
ManagementScope scope = new ManagementScope(adsiPath);
// I've seen this, but I found not necessary:
// scope.Options.EnablePrivileges = true;
ManagementPath osPath = new ManagementPath("Win32_OperatingSystem");
ManagementClass os = new ManagementClass(scope, osPath, null);
ManagementObjectCollection instances;
try
{
instances = os.GetInstances();
}
catch (UnauthorizedAccessException exception)
{
throw new MyException("Not permitted to reboot the host: " + hostName, exception);
}
catch (COMException exception)
{
if (exception.ErrorCode == -2147023174)
{
throw new MyException("Could not reach the target host: " + hostName, exception);
}
throw; // Unhandled
}
foreach (ManagementObject instance in instances)
{
object result = instance.InvokeMethod("Reboot", new object[] { });
uint returnValue = (uint)result;
if (returnValue != 0)
{
throw new MyException("Failed to reboot host: " + hostName);
}
}
}
You can use shutdown command if you need an non-WMI solution.
shutdown [{-l|-s|-r|-a}] [-f] [-m [\\ComputerName]] [-t xx] [-c "message"] [-d[u][p]:xx:yy]
Use the -m for shutting the remote machine.
Refer this link for more info.
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/shutdown.mspx
this will work like sharm
gwmi win32_operatingsystem -ComputerName xxxxxxxxxxxx | Invoke-WmiMethod -Name reboot
I would like to determine the IP address of a printer, using C# (.NET 2.0). I have only the printer share name as set up on the Windows OS, in the format \\PC Name\Printer Name. The printer is a network printer, and has a different IP address to the PC. Does anyone have any pointers?
Thanks in advance for your help.
Regards, Andy.
Just adding an another solution here using .Net Framework 4.0 or higher
Using System.Printing
var server = new PrintServer();
var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
foreach (var queue in queues)
{
string printerName = queue.Name;
string printerPort = queue.QueuePort.Name;
}
Check this question: How to get Printer Info in C#.NET?. I think that you have to get the property PortName from the WMI properties.
I know this is an old post, but I had the same issue where I was able to get the Printer Port name, but not the IP. In my case I couldn't rely on the Port Name being IP_[IP Address] but found how to get hold of the actual IP from the port name.
Windows stores the information about ports in the registry under
HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\[port name]
This key contains the values set up in the port configuration page, including IP address and port number.
A quick C# example to get the IP address
using Microsoft.Win32;
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"System\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\" + printerPortName, RegistryKeyPermissionCheck.Default, System.Security.AccessControl.RegistryRights.QueryValues);
if (key != null)
{
String IP = (String)key.GetValue("IPAddress", String.Empty, RegistryValueOptions.DoNotExpandEnvironmentNames);
}
Using WIN32_Printer class is not enough here. It should be combined with Win32_TCPIPPrinterPort class.
Below is the code which should help:
static void Main(string[] args)
{
var scope = new ManagementScope(#"\root\cimv2");
scope.Connect();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
var results = searcher.Get();
Console.WriteLine("Network printers list:");
foreach (var printer in results)
{
var portName = printer.Properties["PortName"].Value;
var searcher2 = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where Name LIKE '" + portName + "'");
var results2 = searcher2.Get();
foreach (var printer2 in results2)
{
Console.WriteLine("Name:" + printer.Properties["Name"].Value);
//Console.WriteLine("PortName:" + portName);
Console.WriteLine("PortNumber:" + printer2.Properties["PortNumber"].Value);
Console.WriteLine("HostAddress:" + printer2.Properties["HostAddress"].Value);
}
Console.WriteLine();
}
Console.ReadLine();
}
string printerName = "POS-80C";
LocalPrintServer server = new LocalPrintServer();
PrintQueue printQueue = server.GetPrintQueue(printerName);
string portName = printQueue.QueuePort.Name;
string portNumber = "";
string hostAddress = "";
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where Name LIKE '" + portName + "'");
var results = searcher.Get();
foreach (var printer in results)
{
portNumber = (printer.Properties["PortNumber"].Value).ToString();
hostAddress = (printer.Properties["HostAddress"].Value).ToString();
}
Is this printer set up in a network which has Active Directory?
Or is this on your own local network with just a switch and your printer plugged into it?
If it is the former, then you should be able to query for it based on the "printer name". This article show how to get c# .net to connect to the AD. But this does require some knowledge of AD servers in your network.
This solution seems a bit long to me, but may be a good starting point?
Based on the link How to get Printer Info in .NET? (Thanks, Panos, I was already looking at the link!), I have the following solution from Panos's answer:
using System.Management;
...
string printerName = "YourPrinterName";
string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection coll = searcher.Get();
foreach (ManagementObject printer in coll)
{
string portName = printer["PortName"].ToString();
if(portName.StartsWith("IP_"))
{
Console.WriteLine(string.Format("Printer IP Address: {0}", portName.Substring(3)));
}
}
Obviously, this only works if the port name for the printer is given in the format "IP_IPAddress", which is I believe is the default.
I'm trying to write a voting server and client, so you start the program and it displays the voting form and you can vote on various items. For the server part I've got the server running in a separate thread, but it's using a lot of CPU, how do I reduce the amount of CPU it's using?
this is my server:
Form1 main = new Form1();
try
{
IPAddress ipAd = IPAddress.Parse(main.ipAddress); //use local m/c IP address, and use the same in the client
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, 55548);
/* Start Listeneting at the specified port */
myList.Start();
while (true)
{
string message = "";
Socket s = myList.AcceptSocket();
if (main.users.Contains(s.RemoteEndPoint.ToString()) == false)
main.users.Add(s.RemoteEndPoint.ToString());
byte[] b = new byte[500];
int k = s.Receive(b);
for (int i = 0; i < k; i++)
{
message += (Convert.ToString(b[i]));
}
string[] messageArray = message.Split('/');
MessageBox.Show("help");
if (messageArray[0].CompareTo("vote") == 0)
{
if (main.votes.ContainsKey(messageArray[1]) != true) main.votes.Add(messageArray[1], 1);
else main.votes[messageArray[1]]++;
string[] temp = main.textBox1.Text.Split(' ');
int numVotes = Convert.ToInt32(temp[1]);
numVotes++;
main.textBox1.Text = temp[0] + " " + Convert.ToString(numVotes);
}
if (messageArray[0].CompareTo("start") == 0)
{
main.updateEverything();
}
if(messageArray[0].CompareTo("withdraw") == 0)
{
main.votes[messageArray[1]]--;
string[] temp = main.textBox1.Text.Split(' ');
int numVotes = Convert.ToInt32(temp[1]);
numVotes--;
main.textBox1.Text = temp[0] + " " + Convert.ToString(numVotes);
}
/* clean up */
s.Close();
myList.Stop();
}
}
catch (Exception e)
{
Console.WriteLine("Error..... " + e.StackTrace);
}
You are using a blocking type of connection. The loop you create causes a CPU overhead because of the TcpListener.AcceptConnection(). Your solution is to accept non-blocking socket connections, which is done by receiving data from socket asynchronously.
Here's the msdn link that explains how it works.
http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx
I see you have string concatenations which basically affects performance; try using a StringBuilder - the message variable should be of type StringBuilder.
The code below performs a WMI query to enumerate the working devices on my computer (the OS is windows 7). It retrieves one USB serial port when I have several devices connected to USB plugs. Therefore I have three questions on the topic:
1) Does all USB plugs have a separate com port or is there one com port for all the USB?
2) If I send an array of string to the USB serial port, how will it reach the specific device?
3) Can I extract the USB port from this query to keep it as a string?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Windows.Forms;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
MyClass x = new MyClass();
var com = x.GetCOMs();
foreach (string port in com)
{
Console.WriteLine(port);
}
Console.ReadLine();
}
}
class MyClass
{
public List<string> GetCOMs()
{
List<string> coms = new List<string>();
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0");
foreach (ManagementObject obj in searcher.Get())
{
object captionObj = obj["Caption"];
if (captionObj != null)
{
string caption = captionObj.ToString();
if (caption.Contains("(COM"))
{
coms.Add(caption);
}
}
}
m_ParseCOMs(ref coms);
}
catch (ManagementException ex)
{
MessageBox.Show("An error occurred while querying for WMI data: " + ex.Message);
return coms;
}
return coms;
}
private void m_ParseCOMs(ref List<string> comPorts)
{
string[] temp;
List<string> temp2 = new List<string>();
int index = 0;
foreach (string s in comPorts)
{
string temp3 = "";
temp = s.Split(' ');
temp3 += temp[temp.Length - 1] + " - ";
for (int i = 0; i < temp.Length - 1; i++)
{
temp3 += temp[i] + " ";
}
temp2.Insert(index, temp3);
index++;
}
comPorts = temp2;
}
}
}
Many thanks in advance!
I'm working on an application which scans a given networkrange for computers. From the found clients I need to get the IP, hostname, Mac address, OS Information etc.
Now, I have all of the above, except the OS version. Does anyone have a clue on how I could achieve this?
I'm stuck.
Thanks in advance, Christophe
You could run Nmap using Process class from System.Diagnostics and parse the result:
var process = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
Arguments = "/c nmap -O -v targethost",
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true
}
};
process.Start();
while (!process.StandardOutput.EndOfStream)
{
string line = process.StandardOutput.ReadLine();
// here you can parse to obtain the operating system
}
Creating your own OS detector in C# would be hard but if you are interested in an overview of how it works you can find it in this Nmap chapter: Chapter 8. Remote OS Detection
Use WMI, add reference to - System.Management dll and provide namespace, use following code with appropriate parameters-
ManagementScope scope = new ManagementScope();
try
{
ConnectionOptions conOptions = new ConnectionOptions();
options.Username = "<Provide username>";
options.Password = "<Provide password>";
options.EnablePrivileges = true;
options.Authority = "ntlmdomain:<domianname>";
scope = new ManagementScope(#"\\<IP address/machine name>\root\CIMV2", options);
scope.Connect();
SelectQuery query = new SelectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
using (ManagementObjectCollection queryCollection = searcher.Get())
{
foreach (ManagementObject m in queryCollection)
{
Console.WriteLine(string.Format("Computer Name : {0}", m["csname"]));
Console.WriteLine(string.Format("Windows Directory : {0}", m["WindowsDirectory"]));
Console.WriteLine(string.Format("Operating System: {0}", m["Caption"]));
Console.WriteLine(string.Format("Version: {0}", m["Version"]);
Console.WriteLine(string.Format("Manufacturer : {0}", m["Manufacturer"]));
}
}
}
catch (Exception ex)
{
}
You must have access right to steal this info else you will get Access right exception.