2

I am having problem with app that uses an external bluetooth device. When device is idle for some time Windows Turn the power to the bluetooth radio. When i uncheck Under Power Management Tab Of the Bluetooth Radio [Allow the computer to turn off this device to save power.] It works. See Image. Same needed to be achieved from C# code. This need to be done from Win7 onwards. Power Management Option I am not familiar with power management option with windows c#. What are my options here? Is there a event or WMI class i can consume ?

I should be able to change these settings when my WPF app running. And restore it while closing.

Fildor
  • 14,510
  • 4
  • 35
  • 67
sPS
  • 71
  • 8
  • Do you use an external library for BT com? Is it for Winforms , WPF, UWP? – Antoine Aug 23 '19 at 06:17
  • No i am not using any external library. System.IO.Ports SerialPort. WPF app which i mentioned in question. Please see. – sPS Aug 23 '19 at 06:19
  • Everything I found in a quick google seems to advertise a certain library ([32feet.net](https://www.nuget.org/packages/32feet.NET)). A native approach seems to be quite a hassle. – Fildor Aug 23 '19 at 06:34
  • @Fildor There is no issue with bluetooth or communication. Did you read the question. Please suggest what options there to keep radio alive in 32feet library ? – sPS Aug 23 '19 at 06:53
  • This can probably be done by registry manipulation, but this requires the user to have registry editing privileges. https://windows10skill.com/solved-allow-computer-to-turn-off-this-device-to-save-power-grayed-out/#3 – Antoine Aug 23 '19 at 07:07
  • Yes, I did in fact read the question, as well as your first comment stating you are using SerialPort, no need to be rude about that. You cannot do this with COM-Emulation, only. So my first guess was to use the BT-Stack. _Maybe_ as @Antoine writes, it is possible to do this via Registry, but that did simply not pop up in my search, so my bet is on the Stack, which as I wrote, can be quite a hassle. That's why in most answers and tutorials using a library is suggested, of which 32feet seems to be a popular and reasonably reliable one. – Fildor Aug 23 '19 at 07:11
  • About Registry: One problem, I run into when doing something like this via registry is often that different Windows Versions will have different keys to be used. So if it is at all possible, you need to figure out, if it is possible in all Windows Versions that you need to support and if so, if all use the same keys. If they use different ones, you'll need to figure out the system you are running on and provide different implementations for each. – Fildor Aug 23 '19 at 07:17
  • Try to disable power saving for USB as well. – Mike Petrichenko Aug 23 '19 at 08:27

2 Answers2

3

You can do this pretty easily with WMI in C#. Make sure you add reference to System.Management (and a using System.Management; statement)

    //BTHUSB will identify physical bluetooth adapters only, if you want all bluetooth devices use 'WHERE PNPClass='Bluetooth' or specific device 'WHERE Name='Intel(R) Wireless Bluetooth(R)'
    ManagementObjectCollection PhysicalBluetoothAdapterResults = new ManagementObjectSearcher("root\\CIMV2", "SELECT DeviceID FROM Win32_PnPEntity WHERE Service='BTHUSB'").Get();
    foreach(ManagementObject PhysicalBluetoothAdapter in PhysicalBluetoothAdapterResults)
    {
        string DeviceID = PhysicalBluetoothAdapter.Properties["DeviceID"].Value.ToString().Replace("\\","\\\\");
        ManagementObjectCollection AdapterPowerOptionResults = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM MSPower_DeviceEnable WHERE InstanceName LIKE '{DeviceID}_%'").Get();
        foreach(ManagementObject AdapterPowerOption in AdapterPowerOptionResults)
        {
            AdapterPowerOption.Properties["enable"].Value = false;
            AdapterPowerOption.Put();
        }
    }

Hope this helps.

-Paul

Paul G
  • 1,219
  • 7
  • 14
  • Great. We need elevated privilege for this. This answers my question. Still need to try on Win7 though. Thanks @Paul G – sPS Aug 27 '19 at 05:58
  • Hey sPS yes unfortunately elevated privs are required. This code "worked on my machine" for all my environments OS's (Win 7, 8,1, 10 1709-1903). This code includes a lazy workaround to pnpdevice->instancename translation but you can get the absolute instance name using the MSWmi_PnPInstanceNames Class in ROOT\WMI – Paul G Aug 27 '19 at 19:50
0

Windows 10 API does have methods that can be used easily to turn on Bluetooth radio:

using Windows.Devices.Radios;

var bluetoothRadio = Radio.GetRadiosAsync().AsTask().Result.
    First(r => r.Kind == RadioKind.Bluetooth);

_bluetoothRadio.SetStateAsync(RadioState.On);

Please note that in order to use these APIs, an assembly reference to Windows.winmd is required. Have a look at Carter's answer.

UPDATE: Looks like the Win 10 SDK references can be added by installing the Microsoft.Windows.SDK.Contracts NuGet package as well.

Amir Mahdi Nassiri
  • 1,190
  • 13
  • 21