friendly name = the name that appears in \"Device Manager\" under \"Ports (COM & LPT).
EDIT: two solutions provided below. One with WMI and another with SetupAPI
Pavel's class SetupDiWrap works great, it just needs a few small tweaks for Windows 7.
Hopefully, this update will help other people struggling (like me) to get COM port numbers from VCP names in Windows 7.
1) The SP_DEVINFO_DATA has changed in Windows 7, the total length is no longer 28 bytes, it is 32 bytes long. This is what works for me:
private struct SP_DEVINFO_DATA
{
/// Size of the structure, in bytes.
public int cbSize;
/// GUID of the device interface class.
public Guid ClassGuid;
/// Handle to this device instance.
public int DevInst;
/// Reserved; do not use.
public ulong Reserved;
}
Note ulong for Reserved instead of an int. Changing uint cbSize to int cbSize saved me a cast later on, otherwise you can leave it as uint.
2) I also wrote the line:
da.cbSize = (uint)Marshal.SizeOf(da);
a bit different, for clarity, to get the cbSize to 32 bits:
da.cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
3) I changed
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
static extern IntPtr SetupDiGetClassDevs(
ref Guid ClassGuid,
IntPtr Enumerator,
IntPtr hwndParent,
int Flags
);
to
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SetupDiGetClassDevs(
ref Guid ClassGuid,
UInt32 Enumerator,
IntPtr hwndParent,
UInt32 Flags
);
The Enumerator is no longer an IntPtr, so you need to call SetupDiGetClassDevs like this:
IntPtr h = SetupDiGetClassDevs(ref guidClone, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_PROFILE);
Note "0" instead of IntPtr.Zero when passing the Enumerator.
The code now runs like a charm in Windows 7!