Thursday, July 02, 2009

Virtual Serial Port detection in .Net 1.1

.Net 2.0 provides SerialPort class which helps you in detecting the available Serial Ports in the machine. However, this is one useful class which v1.1 developers find missing in their tool kit.

As far as 1.1 is concerned we can accomplish it using WMI Classes easily.

private static void GetAvailablePortListUsingWMI()
{
//Below is code pasted from WMICodeCreator
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_SerialPort");

foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("Port : {0}", queryObj["DeviceID"]);
}
}
catch (ManagementException e)
{
Console.WriteLine(e.Message);

}
}


But is this perfect ? At First glance it does give you that impression, but the moment you have your virtual ports running, you are going to run against the wall.

WMI Classes fails in detecting the Virtual Serial Ports.

Solution wasn't too hard to find. I opened up the reflector against the SerialPort Class supported by .Net 2.0 and checked what it was doing and emulated the same with 1.1 code. The SerialPort class use the registry in detecting the ports and it does support the virtual ports as well.

Following is sample of code which runs in background for the SerialPort class in .Net 2.0

private static void GetAvailablePortListUsingRegistry()
{
RegistryKey localMachine = null;
string[] valueNames=null;
RegistryKey key2 = null;
string[] strArray = null;
new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM").Assert();
try
{
localMachine = Registry.LocalMachine;
key2 = localMachine.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM", false);
if (key2 != null)
{
valueNames = key2.GetValueNames();
strArray = new string[valueNames.Length];
for (int i = 0; i <>
{
strArray[i] = (string) key2.GetValue(valueNames[i]);
Console.WriteLine("Port : {0} ",strArray[i]);
}
}
}
catch(Exception ex)
{
Console.WriteLine("Error {0}",ex);
}
finally
{
if (localMachine != null)
{
localMachine.Close();
}
if (key2 != null)
{
key2.Close();
}
CodeAccessPermission.RevertAssert();
}