usando - ¿Cómo puedo averiguar el número de puerto COM de un dispositivo bluetooth en c#?
puertos com win 10 (6)
Mi compañía desarrolló un dispositivo que se comunica con una PC vía Bluetooth usando un puerto COM virtual.
Ahora necesitamos que un usuario empareje un dispositivo con una PC (sistema operativo MS Windows) primero y luego ingrese manualmente su número de puerto en nuestra aplicación (apuesto a que el 95% de los usuarios fallarán en esta tarea).
Así que me gustaría que mi aplicación presente un usuario con una lista de dispositivos vinculados con bluetooth (una lista de sus "nombres descriptivos") y después me gustaría saber cuál es el número de puerto COM del dispositivo seleccionado automáticamente.
¿Cómo puedo hacerlo en c #? (se aprecia una solución independiente de la pila de bluetooth instalada).
Gracias por adelantado.
Entonces, para obtener la información sobre un dispositivo remoto, incluido su nombre, utilizando 32feet.NET, haga lo siguiente:
BluetoothAddress addr = ... ...
BluetoothDeviceInfo info = new BluetoothDeviceInfo(addr);
string name = info.DeviceName;
Si no utiliza la biblioteca, tendrá que P / Invocar BluetoothGetDeviceInfo de Win32.
Primero, cree un Buscador de Objetos de Administración para buscar en la base de datos de WMI:
ManagementObjectSearcher serialSearcher =
new ManagementObjectSearcher("root//CIMV2",
"SELECT * FROM Win32_SerialPort");
A continuación, use LINQ para obtener todos los puertos serie en una consulta:
var query = from ManagementObject s in serialSearcher.Get()
select new { Name = s["Name"], DeviceID = s["DeviceID"], PNPDeviceID = s["PNPDeviceID"] }; // DeviceID -- > PNPDeviceID
Ahora puede imprimir todos los puertos COM, sus nombres descriptivos e incluso puede filtrar a través de sus PNPDeviceID para encontrar la dirección del dispositivo bluetooth. Aquí hay un ejemplo:
foreach (var port in query)
{
Console.WriteLine("{0} - {1}", port.DeviceID, port.Name);
var pnpDeviceId = port.PNPDeviceID.ToString();
if(pnpDeviceId.Contains("BTHENUM"))
{
var bluetoothDeviceAddress = pnpDeviceId.Split(''&'')[4].Split(''_'')[0];
if (bluetoothDeviceAddress.Length == 12 && bluetoothDeviceAddress != "000000000000")
{
Console.WriteLine(" - Address: {0}", bluetoothDeviceAddress);
}
}
}
private static string FindSerialPortForRFIDReaderCore()
{
string serialPort = "";
List<string> ports = new List<string>();
System.Management.ManagementObjectSearcher Searcher = new System.Management.ManagementObjectSearcher("Select * from WIN32_SerialPort");
foreach (System.Management.ManagementObject Port in Searcher.Get())
{
if (Port["PNPDeviceID"].ToString().ToUpper().Contains("MacAddress"))
ports.Add(Port["DeviceID"].ToString());
}
if (ports.Count > 1) // There are more than one Serial Ports created for the bluetooth device.
serialPort = ports.OrderByDescending(p => p).FirstOrDefault();
else if(ports.Count == 1)
serialPort = ports[0];
return serialPort;
}
Tal vez no es lo que estás buscando, y tal vez ya encontraste tu respuesta ...
Acabo de encontrar una pregunta que no es exactamente como la tuya, pero funcionó para mí. Con esta puedes averiguar cuál de tus puertos COM es de un dispositivo Bluetooth: : determina si el puerto serie es COM o SPP normal.
Espero que ayude de alguna manera. Si descubres cómo hacer lo que quieres, házmelo saber. Gracias.
Ver mi respuesta en Widcomm bluetooth: cómo abrir el COM virtual para mi comprensión de la licencia: el uso de la versión binaria es gratuito para uso comercial. Y, también, que soy el mantenedor de la biblioteca.
Entonces una pequeña digresión breve. No soy un gran admirador de los puertos COM virtuales. Siempre parece mucho más fácil utilizar una conexión directa de ''sockets'', en lugar de intentar configurar un puerto COM, y tratar de encontrar el nombre con el que se creó (ver más abajo), y luego abrir un SerialPort para usarlo, y luego, si la conexión se pierde, uno no sabe y simplemente tiene que volver a intentarlo ... ¡Con la biblioteca es mucho más fácil crear y usar esa conexión directa de Bluetooth!
Sin embargo, es posible que desee una solución para su tarea actual en este momento. :-) Entonces, use WMI para encontrar los puertos COM actuales en su lugar y vea si alguno de ellos es para su dispositivo. Por ejemplo en PowerShell:
C:/> Get-WmiObject -query "select DeviceID,PNPDeviceID from Win32_SerialPort"
...
...
DeviceID : COM66
PNPDeviceID : BTHENUM/{00001101-0000-1000-8000-00805F9B34FB}/7&1D80ECD3&0&00803A686519_C00000003
En esa larga cadena larga, uno ve la dirección del dispositivo de destino: 00803A686519. Uno puede usar WMI desde .NET, ejecutar esa consulta, filtrar los que tienen "BTHENUM" y luego analizar la dirección.
Si necesita crear un nuevo puerto COM virtual Bluetooth, use la API BluetoothDeviceInfo.SetServiceState (BluetoothService.SerialPort) de 32feet.NET. Consulte la sección "Puertos serie Bluetooth" en la Guía del usuario, por ejemplo, en http://www.alanjmcf.me.uk/comms/bluetooth/32feet.NET%20--%20User%20Guide.html , y la documentación de la clase en el lanzamiento.
Lamentablemente, la API Win32 nativa que llamamos no dice qué nombre de puerto COM creó. :-( Así que ejecute la consulta WMI antes y después de la llamada para ver qué nombre nuevo apareció (o use System.IO.Ports.SerialPort.GetPortNames como su más simple).
Eso es todo específico de la pila Bluetooth de Microsoft. No he investigado cómo se comportan otras pilas en este sentido. Después de una breve comprobación, los puertos serie de Widcomm aparecen en SerialPort.GetPortNames, pero no en la consulta WMI ...
Logré obtener el nombre bluetooth y el puerto COM tocando la clave de registro
El pseudo código para obtener la información del bluetooth está a continuación:
- enumerar todo el puerto COM disponible en el PNP
- obtener el dispositivo classGuid
- busca la dirección de bluetooth de la claseGuid
- cuando se conoce la dirección del bluetooth, el nombre del bluetooth se puede obtener desde este registro
SYSTEM/CurrentControlSet/Services/BTHPORT/Parameters/Devices
El código está debajo, solo llame al GetBluetoothPort (), devolverá una lista de dispositivos bluetooth, y puede conectarlos pasando el número de puerto COM a la clase SerialPort
public static string[] GetBluetoothPort()
{
Regex regexPortName = new Regex(@"(COM/d+)");
List<string> portList = new List<string>();
ManagementObjectSearcher searchSerial = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity");
foreach (ManagementObject obj in searchSerial.Get()) {
string name = obj["Name"] as string;
string classGuid = obj["ClassGuid"] as string;
string deviceID = obj["DeviceID"] as string;
if (classGuid != null && deviceID != null) {
if (String.Equals(classGuid, "{4d36e978-e325-11ce-bfc1-08002be10318}", StringComparison.InvariantCulture)) {
string[] tokens = deviceID.Split(''&'');
if (tokens.Length >= 4) {
string[] addressToken = tokens[4].Split(''_'');
string bluetoothAddress = addressToken[0];
Match m = regexPortName.Match(name);
string comPortNumber = "";
if (m.Success) {
comPortNumber = m.Groups[1].ToString();
}
if (Convert.ToUInt64(bluetoothAddress, 16) > 0) {
string bluetoothName = GetBluetoothRegistryName(bluetoothAddress);
portList.Add(String.Format("{0} {1} ({2})", bluetoothName, bluetoothAddress, comPortNumber));
}
}
}
}
}
return portList.ToArray();
}
private static string GetBluetoothRegistryName(string address)
{
string deviceName = "";
string registryPath = @"SYSTEM/CurrentControlSet/Services/BTHPORT/Parameters/Devices";
string devicePath = String.Format(@"{0}/{1}", registryPath, address);
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(devicePath)) {
if (key != null) {
Object o = key.GetValue("Name");
byte[] raw = o as byte[];
if (raw != null) {
deviceName = Encoding.ASCII.GetString(raw);
}
}
}
return deviceName;
}