2017-07-25 22 views
10

Czy istnieje sposób na wyliczenie wszystkich portów com bluetooth i uzyskanie ich nazw? I przez nazwę nie mam na myśli COM10, w tym przypadku mam na myśli GNSS:51622 'GNSS Server'.Uzyskaj nazwę kompilatora bluetooth

bluetooth dialog

Korzystanie 32Feet udało mi się znaleźć nazwy portów, ale wciąż nie ma szczęścia mapowanie ich do rzeczywistego portu COM.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("Connecting to Bluetooth"); 
     var client = new BluetoothClient(); 
     Console.WriteLine("DiscoverDevices"); 
     var devices = client.DiscoverDevices(); 
     Console.WriteLine("Enumerating"); 
     foreach (var device in devices) 
     { 
      if (!device.DeviceName.StartsWith("GNSS")) 
       continue; 
      Console.WriteLine(device.DeviceName); 
      try 
      { 
       Console.WriteLine("Getting serial ports"); 
       var serviceRecords = device.GetServiceRecords(BluetoothService.SerialPort); 
       foreach (var serviceRecord in serviceRecords) 
       { 
        var name = GetName(serviceRecord); 
        Console.WriteLine(name); 
       } 

      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Failed to get SerialPort"); 
       Console.WriteLine(ex.ToString()); 
      } 
     } 
     Console.ReadKey(); 
    } 

    private static string GetName(ServiceRecord serviceRecord) 
    { 
     var nameAttribute = serviceRecord.SingleOrDefault(a => a.Id == 0); 
     var name = serviceRecord.GetPrimaryMultiLanguageStringAttributeById(nameAttribute.Id); 
     return name; 
    } 
} 

wyjściowa:

Connecting to Bluetooth DiscoverDevices Enumerating GNSS:51622 Getting serial ports COM1 COM2 COM3 GNSS Server

+0

Czy to pomoże - https://stackoverflow.com/questions/11458835/finding-information-about-all-serial-devices- connected-through-usb-in-c-sharp? – Subbu

+0

@Subbu niestety nie jest w stanie znaleźć wszystkich dostępnych portów COM i nie ma problemu z ustaleniem, który port COM ma nazwę "serwer GNSS". – Peter

+1

Czy możesz spróbować tego kodu? https://gist.github.com/smourier/6f632f37b1cfda085421b079f52d2301 Mam trudności w testowaniu na mojej własnej maszynie –

Odpowiedz

2

mam napisali istotę tutaj https://gist.github.com/peterfoot/b4f61c81023a1e181b9f3940bca344ba z kodem wyliczyć Bluetooth wirtualnych portów COM. Wartość nazwy portu z rekordu usługi jest przechowywana w rejestrze i można ją uzyskać na podstawie ścieżki urządzenia z interfejsów API konfiguracji. Jest wyeksponowany jako RemoteServiceName w kodzie. Na przykład na mojej drukarce Zebra zwraca "Drukarka szeregowa". Nie mam urządzenia do przekazania z wieloma odsłoniętymi usługami, ale da ci to powyższy ciąg obok nazwy urządzenia, np. "Serwer GNSS", "COM1" itd

Kod:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Text; 

namespace BluetoothDiagnostics 
{ 
    public sealed class BluetoothComPort 
    { 
     /// <summary> 
     /// Returns a collection of all the Bluetooth virtual-COM ports on the system. 
     /// </summary> 
     /// <returns></returns> 
     public static IReadOnlyList<BluetoothComPort> FindAll() 
     { 
      List<BluetoothComPort> ports = new List<BluetoothComPort>(); 

      IntPtr handle = NativeMethods.SetupDiGetClassDevs(ref NativeMethods.GUID_DEVCLASS_PORTS, null, IntPtr.Zero, NativeMethods.DIGCF.PRESENT); 
      if (handle != IntPtr.Zero) 
      { 
       try 
       { 


        NativeMethods.SP_DEVINFO_DATA dat = new NativeMethods.SP_DEVINFO_DATA(); 
        dat.cbSize = Marshal.SizeOf(dat); 
        uint i = 0; 

        while (NativeMethods.SetupDiEnumDeviceInfo(handle, i++, ref dat)) 
        { 
         string remoteServiceName = string.Empty; 
         StringBuilder sbid = new StringBuilder(256); 
         int size; 
         NativeMethods.SetupDiGetDeviceInstanceId(handle, ref dat, sbid, sbid.Capacity, out size); 
         Debug.WriteLine(sbid); 
         long addr = GetBluetoothAddressFromDevicePath(sbid.ToString()); 

         // only valid if an outgoing Bluetooth port 
         if (addr != long.MinValue && addr != 0) 
         { 
          IntPtr hkey = NativeMethods.SetupDiOpenDevRegKey(handle, ref dat, NativeMethods.DICS.GLOBAL, 0, NativeMethods.DIREG.DEV, 1); 
          var key = Microsoft.Win32.RegistryKey.FromHandle(new Microsoft.Win32.SafeHandles.SafeRegistryHandle(hkey, true)); 
          object name = key.GetValue("PortName"); 

          var pkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\BTHPORT\\Parameters\\Devices\\" + addr.ToString("x12")); 
          if (pkey != null) 
          { 
           foreach (string nm in pkey.GetSubKeyNames()) 
           { 
            if (nm.StartsWith("ServicesFor")) 
            { 
             var skey = pkey.OpenSubKey(nm); 
             string s = sbid.ToString(); 

             //bluetooth service uuid from device id string 
             int ifirst = s.IndexOf("{"); 
             string uuid = s.Substring(ifirst, s.IndexOf("}") - ifirst+1); 
             var ukey = skey.OpenSubKey(uuid); 

             // instance id from device id string 
             string iid = s.Substring(s.LastIndexOf("_")+1); 
             var instKey = ukey.OpenSubKey(iid); 

             // registry key contains service name as a byte array 
             object o = instKey.GetValue("PriLangServiceName"); 
             if(o != null) 
             { 
              byte[] chars = o as byte[]; 
              remoteServiceName = Encoding.UTF8.GetString(chars).Trim(); 
             } 
            } 
           } 
          } 
          ports.Add(new BluetoothComPort(sbid.ToString(), addr, name.ToString(), remoteServiceName)); 
          key.Dispose(); 
         } 
        } 

       } 
       finally 
       { 
        NativeMethods.SetupDiDestroyDeviceInfoList(handle); 
       } 
      } 

      return ports; 
     } 

     private string _deviceId; 
     private long _bluetoothAddress; 
     private string _portName; 
     private string _remoteServiceName; 

     internal BluetoothComPort(string deviceId, long bluetoothAddress, string portName, string remoteServiceName) 
     { 
      _deviceId = deviceId; 
      _bluetoothAddress = bluetoothAddress; 
      _portName = portName; 
      _remoteServiceName = remoteServiceName; 
     } 

     public string DeviceId 
     { 
      get 
      { 
       return _deviceId; 
      } 
     } 

     public long BluetoothAddress 
     { 
      get 
      { 
       return _bluetoothAddress; 
      } 
     } 

     public string PortName 
     { 
      get 
      { 
       return _portName; 
      } 
     } 

     public string RemoteServiceName 
     { 
      get 
      { 
       return _remoteServiceName; 
      } 
     } 


     private static long GetBluetoothAddressFromDevicePath(string path) 
     { 
      if (path.StartsWith("BTHENUM")) 
      { 
       int start = path.LastIndexOf('&'); 
       int end = path.LastIndexOf('_'); 
       string addressString = path.Substring(start + 1, (end - start) - 1); 

       // may return zero if it is an incoming port (we're not interested in these) 
       return long.Parse(addressString, System.Globalization.NumberStyles.HexNumber); 

      } 

      // not a bluetooth port 
      return long.MinValue; 
     } 

     private static class NativeMethods 
     { 
      // The SetupDiGetClassDevs function returns a handle to a device information set that contains requested device information elements for a local machine. 
      [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
      internal static extern IntPtr SetupDiGetClassDevs(
       ref Guid classGuid, 
       [MarshalAs(UnmanagedType.LPTStr)] string enumerator, 
       IntPtr hwndParent, 
       DIGCF flags); 

      // The SetupDiEnumDeviceInfo function returns a SP_DEVINFO_DATA structure that specifies a device information element in a device information set. 
      [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
      [return: MarshalAs(UnmanagedType.Bool)] 
      internal static extern bool SetupDiEnumDeviceInfo(
       IntPtr deviceInfoSet, 
       uint memberIndex, 
       ref SP_DEVINFO_DATA deviceInfoData); 

      // The SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory. 
      [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
      [return: MarshalAs(UnmanagedType.Bool)] 
      internal static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet); 

      // The SetupDiGetDeviceInstanceId function retrieves the device instance ID that is associated with a device information element. 
      [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
      [return: MarshalAs(UnmanagedType.Bool)] 
      internal static extern bool SetupDiGetDeviceInstanceId(
       IntPtr deviceInfoSet, 
       ref SP_DEVINFO_DATA deviceInfoData, 
       System.Text.StringBuilder deviceInstanceId, 
       int deviceInstanceIdSize, 
       out int requiredSize); 

      //static Guid GUID_DEVCLASS_BLUETOOTH = new Guid("{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}"); 
      internal static Guid GUID_DEVCLASS_PORTS = new Guid("{4d36e978-e325-11ce-bfc1-08002be10318}"); 

      [DllImport("setupapi.dll", SetLastError = true)] 
      internal static extern IntPtr SetupDiOpenDevRegKey(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, 
       DICS Scope, int HwProfile, DIREG KeyType, int samDesired); 

      [Flags] 
      internal enum DICS 
      { 
       GLOBAL = 0x00000001, // make change in all hardware profiles 
       CONFIGSPECIFIC = 0x00000002, // make change in specified profile only 
      } 

      internal enum DIREG 
      { 
       DEV = 0x00000001,   // Open/Create/Delete device key 
       DRV = 0x00000002,   // Open/Create/Delete driver key 
      } 

      // changes to follow. 
      // SETUPAPI.H 
      [Flags()] 
      internal enum DIGCF 
      { 
       PRESENT = 0x00000002, // Return only devices that are currently present in a system. 
       ALLCLASSES = 0x00000004, // Return a list of installed devices for all device setup classes or all device interface classes. 
       PROFILE = 0x00000008, // Return only devices that are a part of the current hardware profile. 
      } 


      [StructLayout(LayoutKind.Sequential)] 
      internal struct SP_DEVINFO_DATA 
      { 
       internal int cbSize; // = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA)); 
       internal Guid ClassGuid; 
       internal uint DevInst; 
       internal IntPtr Reserved; 
      } 
     } 
    } 
}