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.
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.
A long time ago I wrote a utility for a client to do just this, but for a GPS rather than a modem.
I have just looked at it, and bits that jump-out as being possibly helpful are:
(You call this bit in a loop with incrementing nDevice)
and then
which finds the name of the device.
Hopefully that will help you in the right direction.
The C++ version based on @Will Dean answer.
Glad it worked.
You could try:
Regex.Match(tmpstring, @"COM\s\d+").ToString()
for your string matching.
As .NET style points, I'd add a "using System.Text", and I wouldn't start local variable names with capitals, and if I was feeling really virtuous, I would probably put the SetupDiDestroyDeviceInfoList in a finally{} clause.
After you determine a Serial Port device is the one you want (by looking at its Friendly Name, by checking its parent device etc.), the proper way to get the port's name would probably be:
SetupDiOpenDevRegKey(hDevInfo, devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)
to get theHKEY
to the so-called device keyREG_SZ
value "PortName"HKEY
:)However, this might require so much interop in C# it's not even funny, so I don't blame you if you keep to the string parsing solution.
Used the method posted by LiGenChen. The method ComPortSetupAPISetupDiClassGuids gave the best time and friendly name.