I have a GSM modem connected via USB. The modem creates 2 serial ports. The first is automatically attached to the modem, the second shows in Device Manager as "HUAWEI Mobile Connect - 3G PC UI Interface (COM6)"
The second port is used to get vital information from the modem, such as signal quality; to send and receive text messages; and a whole host of other functions.
I am writing an application that will wrap up some of the features provided by the second port. What I need is a sure fire method of identifying which COM port is the spare one. Iterating the ports and checking a response to "ATE0" is not sufficient. The modem's port is usually the lower numbered one, and when a dial up connection is not active, it will respond to "ATE0" the same as the second port.
What I was thinking of doing is iterating the ports and checking their friendly name, as it shows in Device Manager. That way I can link the port in my application to the port labelled "HUAWEI Mobile Connect - 3G PC UI Interface (COM6)" in Device Manager. I've just not found any information yet that will allow me to get that name programmatically.
The information posted by Will Dean was most helpful. This is the code that eventually worked for me. Everything in the PInvoke class was taken verbatim from http://www.pinvoke.net . I did have to change a data type here or there to make it work (like when using an enum instead of a uint) but it should be easy to figure out.
internal static string GetComPortByDescription(string Description)
{
string Result = string.Empty;
Guid guid = PInvoke.GUID_DEVCLASS_PORTS;
uint nDevice = 0;
uint nBytes = 300;
byte[] retval = new byte[nBytes];
uint RequiredSize = 0;
uint PropertyRegDataType = 0;
PInvoke.SP_DEVINFO_DATA devInfoData = new PInvoke.SP_DEVINFO_DATA();
devInfoData.cbSize = Marshal.SizeOf(typeof(PInvoke.SP_DEVINFO_DATA));
IntPtr hDeviceInfo = PInvoke.SetupDiGetClassDevs(
ref guid,
null,
IntPtr.Zero,
PInvoke.DIGCF.DIGCF_PRESENT);
while (PInvoke.SetupDiEnumDeviceInfo(hDeviceInfo, nDevice++, ref devInfoData))
{
if (PInvoke.SetupDiGetDeviceRegistryProperty(
hDeviceInfo,
ref devInfoData,
PInvoke.SPDRP.SPDRP_FRIENDLYNAME,
out PropertyRegDataType,
retval,
nBytes,
out RequiredSize))
{
if (System.Text.Encoding.Unicode.GetString(retval).Substring(0, Description.Length).ToLower() ==
Description.ToLower())
{
string tmpstring = System.Text.Encoding.Unicode.GetString(retval);
Result = tmpstring.Substring(tmpstring.IndexOf("COM"),tmpstring.IndexOf(')') - tmpstring.IndexOf("COM"));
} // if retval == description
} // if (PInvoke.SetupDiGetDeviceRegistryProperty( ... SPDRP_FRIENDLYNAME ...
} // while (PInvoke.SetupDiEnumDeviceInfo(hDeviceInfo, nDevice++, ref devInfoData))
PInvoke.SetupDiDestroyDeviceInfoList(hDeviceInfo);
return Result;
}
I think the line Result = tmpstring.Substring(tmpstring.IndexOf("COM"),tmpstring.IndexOf(')') - tmpstring.IndexOf("COM"));
is a little clumsy, suggestions on how to clean it up would be appreciated.
Thanks for your help with this matter Will, without you, I'd still be searching google.