I had been using the code below for a console application in Visual Studio on Windows 8 to return the description and device ID of connected serial devices. I was using a mo
Ok, I think I see the issue now (I will add a new answer, but won't replace the old in case someone finds the information useful).
Win32_SerialPort
only detects hardware serial ports (e.g. RS232).
Win32_PnPEntity
identifies plug-and-play devices including hardware and virtual serial ports (e.g. COM port created by the FTDI driver).
To use Win32_PnPEntity
to identify a driver requires a little extra work. The following code identifies all COM ports on the system and produces a list of said ports. From this list, you may identify the appropriate COM port number to create your SerialPort object.
// Class to contain the port info.
public class PortInfo
{
public string Name;
public string Description;
}
// Method to prepare the WMI query connection options.
public static ConnectionOptions PrepareOptions ( )
{
ConnectionOptions options = new ConnectionOptions ( );
options . Impersonation = ImpersonationLevel . Impersonate;
options . Authentication = AuthenticationLevel . Default;
options . EnablePrivileges = true;
return options;
}
// Method to prepare WMI query management scope.
public static ManagementScope PrepareScope ( string machineName , ConnectionOptions options , string path )
{
ManagementScope scope = new ManagementScope ( );
scope . Path = new ManagementPath ( @"\\" + machineName + path );
scope . Options = options;
scope . Connect ( );
return scope;
}
// Method to retrieve the list of all COM ports.
public static List<PortInfo> FindComPorts ( )
{
List<PortInfo> portList = new List<PortInfo> ( );
ConnectionOptions options = PrepareOptions ( );
ManagementScope scope = PrepareScope ( Environment . MachineName , options , @"\root\CIMV2" );
// Prepare the query and searcher objects.
ObjectQuery objectQuery = new ObjectQuery ( "SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0" );
ManagementObjectSearcher portSearcher = new ManagementObjectSearcher ( scope , objectQuery );
using ( portSearcher )
{
string caption = null;
// Invoke the searcher and search through each management object for a COM port.
foreach ( ManagementObject currentObject in portSearcher . Get ( ) )
{
if ( currentObject != null )
{
object currentObjectCaption = currentObject [ "Caption" ];
if ( currentObjectCaption != null )
{
caption = currentObjectCaption . ToString ( );
if ( caption . Contains ( "(COM" ) )
{
PortInfo portInfo = new PortInfo ( );
portInfo . Name = caption . Substring ( caption . LastIndexOf ( "(COM" ) ) . Replace ( "(" , string . Empty ) . Replace ( ")" , string . Empty );
portInfo . Description = caption;
portList . Add ( portInfo );
}
}
}
}
}
return portList;
}
Your Windows 8 user profile probably included full administrator privileges while your Windows 10 user profile is a standard user. Because your Windows 10 user profile is a standard user, you must adjust some access permissions.
Run the Computer Management
utility.
Go to Computer Management > Services and Applications > WMI Control
.
Go to Actions > WMI Control > More Actions > Properties
to open the WMI Control Properties
window.
Under the Security
tab, select Root
, then press Security
.
In the Security for Root
dialog, select your username or the group you belong to. Select Allow for Permissions > Execute Methods
. Click OK
to close the dialog.
Repeat the previous step for CIMV2
.
Try running again with these new permissions.
A bit smaller solution than Juderb
public static List<string> FindComPorts()
{
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0"))
{
return searcher.Get().OfType<ManagementBaseObject>()
.Select(port => Regex.Match(port["Caption"].ToString(), @"\((COM\d*)\)"))
.Where(match => match.Groups.Count >= 2)
.Select(match => match.Groups[1].Value).ToList();
}
}
Tested this on win7 + win10. Btw, you can add extra search criteria to the regex if you want (or just add a new Where clause)