using winform to develop client, the client need to turn off bluetooth after communication and when need to communication with bluetooth, turn on bluetooth.
On Windows 10, the settings -> devices -> bluetooth and other devices has the switch to turn on bluetooth or turn off. is possible to use some windows api to turn on or turn off the bluetooth?
BluetoothSetServiceState, as described above, does nothing with Bluetooth hardware itself. It simple adds/removes drivers for paired Bluetooth enabled device. If you have paired device with, let say, Serial Port Profile, you can use this method to install vCOMs for that service and/or removes them. Nothing more.
The second part of the answer above is correct. However it has one very important limitation: the application uses it must has the same "bits" as the OS. If your application runs on 64bit OS it (the app) must be 64bits as well. 32bits app on 64bits OS will not work because the RadioManager interface (internally it uses COM based Managers that actually does the job) registered only for 64bits (as 64bits inproc COM server). RadioState (when you set it) simple checks if the RadioManager is registered by calling CoCreateInstance() and then calls its methods (see code below that does exactly the same what WinRT API does).
So instead of using that API you can directly call to RadioManager interface (and object):
private static readonly Guid CLSID_BluetoothRadioManager = new Guid("{afd198ac-5f30-4e89-a789-5ddf60a69366}");
public const UInt32 CLSCTX_INPROC_SERVER = 1;
[DllImport("ole32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern Int32 CoCreateInstance(
[param: MarshalAs(UnmanagedType.LPStruct), In] Guid rclsid,
[param: MarshalAs(UnmanagedType.SysInt), In] IntPtr pUnkOuter,
[param: MarshalAs(UnmanagedType.U4), In] UInt32 dwClsContext,
[param: MarshalAs(UnmanagedType.LPStruct), In] Guid riid,
[param: MarshalAs(UnmanagedType.Interface), Out] out Object ppv);
[ComImport]
[Guid("6CFDCAB5-FC47-42A5-9241-074B58830E73")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMediaRadioManager
{
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetRadioInstances(
[param: MarshalAs(UnmanagedType.Interface), Out] out IRadioInstanceCollection ppCollection);
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 OnSystemRadioStateChange(
[param: In] SYSTEM_RADIO_STATE sysRadioState,
[param: MarshalAs(UnmanagedType.U4), In] UInt32 uTimeoutSec);
};
[ComImport]
[Guid("E5791FAE-5665-4E0C-95BE-5FDE31644185")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IRadioInstanceCollection
{
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetCount(
[param: MarshalAs(UnmanagedType.U4), Out] out UInt32 pcInstance);
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetAt(
[param: MarshalAs(UnmanagedType.U4), In] UInt32 uIndex,
[param: MarshalAs(UnmanagedType.Interface), Out] out IRadioInstance ppRadioInstance);
};
[ComImport]
[Guid("70AA1C9E-F2B4-4C61-86D3-6B9FB75FD1A2")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IRadioInstance
{
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetRadioManagerSignature(
[param: Out] out Guid pguidSignature);
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetInstanceSignature(
[param: MarshalAs(UnmanagedType.BStr), Out] out String pbstrId);
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetFriendlyName(
[param: MarshalAs(UnmanagedType.U4), In] UInt32 lcid,
[param: MarshalAs(UnmanagedType.BStr), Out] out String pbstrName);
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 GetRadioState(
[param: Out] out DEVICE_RADIO_STATE pRadioState);
[PreserveSig]
[return: MarshalAs(UnmanagedType.I4)]
Int32 SetRadioState(
[param: In] DEVICE_RADIO_STATE radioState,
[param: MarshalAs(UnmanagedType.U4), In] UInt32 uTimeoutSec);
[PreserveSig]
[return: MarshalAs(UnmanagedType.Bool)]
Boolean IsMultiComm();
[PreserveSig]
[return: MarshalAs(UnmanagedType.Bool)]
Boolean IsAssociatingDevice();
};
private enum DEVICE_RADIO_STATE : int
{
DRS_RADIO_ON = 0,
DRS_SW_RADIO_OFF = 1,
DRS_HW_RADIO_OFF = 2,
DRS_SW_HW_RADIO_OFF = 3,
DRS_HW_RADIO_ON_UNCONTROLLABLE = 4,
DRS_RADIO_INVALID = 5,
DRS_HW_RADIO_OFF_UNCONTROLLABLE = 6,
DRS_RADIO_MAX = DRS_HW_RADIO_OFF_UNCONTROLLABLE
};
private Boolean ChangeRadioState(Boolean TurnOn)
{
// Try to get Bluetooth Radio Manager interface.
Object oRadioMan;
Int32 Res = CoCreateInstance(CLSID_BluetoothRadioManager, IntPtr.Zero, CLSCTX_INPROC_SERVER,
typeof(IMediaRadioManager).GUID, out oRadioMan);
if (Res != 0x00000000)
return false;
IMediaRadioManager RadioMan = oRadioMan as IMediaRadioManager;
IRadioInstanceCollection Radios;
if (RadioMan.GetRadioInstances(out Radios) != 0x00000000)
return false;
UInt32 Cnt = 0;
if (Radios.GetCount(out Cnt) != 0x00000000)
return false;
if (Cnt == 0)
return false;
IRadioInstance Radio;
if (Radios.GetAt(0, out Radio) != 0x00000000)
return false;
DEVICE_RADIO_STATE State;
if (TurnOn)
State = DEVICE_RADIO_STATE.DRS_RADIO_ON;
else
State = DEVICE_RADIO_STATE.DRS_SW_RADIO_OFF;
if (Radio.SetRadioState(State, 10) != 0x00000000)
return false;
return true;
}
As you can see this way gives you more control and also can be used with WiFi adapter (with querying WiFi Radio interface). Back to OS bits: it is OK for .NET applications with Any CPU configuration but can be a big problem for native applications (C++, VCL, etc) that can be compiled as 32bits but run on 64bits OS. Also, this may not work on Windows 8.
We used that way in our Bluetooth Framework library early. But then switched to another, 100% working, OS bits independent way. Unfortunately I can not share that code here.