see - usb serial port driver windows 7
¿Cómo obtengo el nombre descriptivo de un puerto COM en Windows? (6)
Hace mucho tiempo escribí una utilidad para un cliente para hacer justamente esto, pero para un GPS en lugar de un módem.
Acabo de verlo, y los bits que saltan como posiblemente útiles son:
GUID guid = GUID_DEVCLASS_PORTS;
SP_DEVICE_INTERFACE_DATA interfaceData;
ZeroMemory(&interfaceData, sizeof(interfaceData));
interfaceData.cbSize = sizeof(interfaceData);
SP_DEVINFO_DATA devInfoData;
ZeroMemory(&devInfoData, sizeof(devInfoData));
devInfoData.cbSize = sizeof(devInfoData);
if(SetupDiEnumDeviceInfo(
hDeviceInfo, // Our device tree
nDevice, // The member to look for
&devInfoData
))
{
DWORD regDataType;
BYTE hardwareId[300];
if(SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, ®DataType, hardwareId, sizeof(hardwareId), NULL))
{
...
(Usted llama a este bit en un bucle con el incremento de nDevice)
y entonces
BYTE friendlyName[300];
if(SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, NULL, friendlyName, sizeof(friendlyName), NULL))
{
strFriendlyNames += (LPCTSTR)friendlyName;
strFriendlyNames += ''/n'';
}
que encuentra el nombre del dispositivo.
Espero que eso te ayude en la dirección correcta.
Tengo un módem GSM conectado a través de USB. El módem crea 2 puertos serie. El primero se conecta automáticamente al módem, el segundo se muestra en el Administrador de dispositivos como "HUAWEI Mobile Connect - Interfaz de interfaz de usuario de PC 3G (COM6)"
El segundo puerto se usa para obtener información vital del módem, como la calidad de la señal; para enviar y recibir mensajes de texto; y toda una serie de otras funciones.
Estoy escribiendo una aplicación que resumirá algunas de las características proporcionadas por el segundo puerto. Lo que necesito es un método seguro para identificar qué puerto COM es el de repuesto. Iterar los puertos y verificar una respuesta a "ATE0" no es suficiente. El puerto del módem suele ser el número más bajo, y cuando una conexión de acceso telefónico no está activa, responderá a "ATE0" igual que el segundo puerto.
Lo que estaba pensando hacer es iterar los puertos y verificar su nombre descriptivo, como se muestra en el Administrador de Dispositivos. De esa forma puedo vincular el puerto de mi aplicación al puerto etiquetado como "HUAWEI Mobile Connect - Interfaz de interfaz de usuario de PC 3G (COM6)" en el Administrador de dispositivos. Todavía no he encontrado ninguna información que me permita obtener ese nombre programáticamente.
Me alegro de que funcionó.
Tu podrías intentar:
Regex.Match (tmpstring, @ "COM / s / d +"). ToString ()
para su coincidencia de cadenas.
Como puntos de estilo .NET, agregaría un "using System.Text", y no comenzaría nombres de variables locales con mayúsculas, y si me sintiera realmente virtuoso, probablemente pondría SetupDiDestroyDeviceInfoList en una cláusula finally {} .
Después de determinar que un dispositivo de puerto serie es el que desea (al mirar su nombre descriptivo, verificando su dispositivo principal, etc.), la forma correcta de obtener el nombre del puerto sería probablemente:
- invocar
SetupDiOpenDevRegKey(hDevInfo, devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ)
para obtener elHKEY
a la llamada clave de dispositivo - consulta esta clave de registro para el valor
REG_SZ
"PortName" - no te olvides de cerrar el
HKEY
:)
Sin embargo, esto podría requerir tanta interoperabilidad en C # que ni siquiera es divertido, así que no te culpo si sigues con la solución de análisis de cadenas.
Usó el método publicado por LiGenChen . El método ComPortSetupAPISetupDiClassGuids dio el mejor nombre de tiempo y fácil de usar.
La información publicada por Will Dean fue de gran ayuda. Este es el código que finalmente funcionó para mí. Todo en la clase PInvoke fue tomado textualmente de http://www.pinvoke.net . Tuve que cambiar un tipo de datos aquí o allá para que funcione (como cuando se usa una enumeración en lugar de una uint) pero debería ser fácil de descifrar.
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;
}
Creo que la línea Result = tmpstring.Substring(tmpstring.IndexOf("COM"),tmpstring.IndexOf('')'') - tmpstring.IndexOf("COM"));
es un poco torpe, se apreciarán sugerencias sobre cómo limpiarlo.
Gracias por su ayuda con este asunto Will, sin usted, seguiría buscando en Google.
La versión de C ++ basada en la respuesta de @Will Dean.
#include <windows.h>
#include <initguid.h>
#include <devguid.h>
#include <setupapi.h>
void enumerateSerialPortsFriendlyNames()
{
SP_DEVINFO_DATA devInfoData = {};
devInfoData.cbSize = sizeof(devInfoData);
// get the tree containing the info for the ports
HDEVINFO hDeviceInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS,
0,
nullptr,
DIGCF_PRESENT
);
if (hDeviceInfo == INVALID_HANDLE_VALUE)
{
return;
}
// iterate over all the devices in the tree
int nDevice = 0;
while (SetupDiEnumDeviceInfo(hDeviceInfo, // Our device tree
nDevice++, // The member to look for
&devInfoData))
{
DWORD regDataType;
DWORD reqSize = 0;
// find the size required to hold the device info
SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, nullptr, nullptr, 0, &reqSize);
BYTE hardwareId[reqSize > 1 ? reqSize : 1];
// now store it in a buffer
if (SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, ®DataType, hardwareId, sizeof(hardwareId), nullptr))
{
// find the size required to hold the friendly name
reqSize = 0;
SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &reqSize);
BYTE friendlyName[reqSize > 1 ? reqSize : 1];
// now store it in a buffer
if (!SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, friendlyName, sizeof(friendlyName), nullptr))
{
// device does not have this property set
memset(friendlyName, 0, reqSize > 1 ? reqSize : 1);
}
// use friendlyName here
}
}
}