Казалось бы, такая простая задача, а я так и не нашел приемлемого решения. Что я пробовал (с воспроизведением музыки через подключенный по Bluetooth динамик, чтобы действительно знать состояние радио):
devcon disable USB\VID_8087&PID_07DC&REV_0001
(это HW ID моего Bluetooth адаптера)... для работы требуется перезагрузка...Disable-NetAdapter "Bluetooth Network Connection 3"
(это перевод названия моего Bluetooth-адаптера)... это отключает PAN-драйвер, но Bluetooth-динамик продолжает воспроизводить музыку...net stop bthserv
... фактически не выключает радио (BT колонка продолжает играть музыку)ms-settings:bluetooth
или explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms
... открывает панель настроек Bluetooth, но мне все равно приходится нажимать на тумблерЯ не могу поверить, что Microsoft может быть настолько невежественной, чтобы не предоставить такую команду...
Это является сложной задачей из-за необходимости взаимодействия с WinRT, так, но это возможно в чисто в PowerShell:
[CmdletBinding()] Param (
[Parameter(Mandatory=$true)][ValidateSet('Off', 'On')][string]$BluetoothStatus
)
If ((Get-Service bthserv).Status -eq 'Stopped') { Start-Service bthserv }
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
Function Await($WinRtTask, $ResultType) {
$asTask = $asTaskGeneric.MakeGenericMethod($ResultType)
$netTask = $asTask.Invoke($null, @($WinRtTask))
$netTask.Wait(-1) | Out-Null
$netTask.Result
}
[Windows.Devices.Radios.Radio,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
[Windows.Devices.Radios.RadioAccessStatus,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
Await ([Windows.Devices.Radios.Radio]::RequestAccessAsync()) ([Windows.Devices.Radios.RadioAccessStatus]) | Out-Null
$radios = Await ([Windows.Devices.Radios.Radio]::GetRadiosAsync()) ([System.Collections.Generic.IReadOnlyList[Windows.Devices.Radios.Radio]])
$bluetooth = $radios | ? { $_.Kind -eq 'Bluetooth' }
[Windows.Devices.Radios.RadioState,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
Await ($bluetooth.SetStateAsync($BluetoothStatus)) ([Windows.Devices.Radios.RadioAccessStatus]) | Out-Null
Чтобы использовать его, сохранить это файл PS1, например по Bluetooth.пс1`. Если вы еще'т уже, следуйте инструкциям в разделе включение скриптов тег Вики в PowerShell, чтобы включить выполнение скриптов в системе. Затем вы можете запустить его в командной строке PowerShell такой:
.\bluetooth.ps1 -BluetoothStatus On
Чтобы выключить Bluetooth, проходят "отсечки" вместо.
Для запуска из пакетного файла:
powershell -command .\bluetooth.ps1 -BluetoothStatus On
Предупреждение: если Служба поддержки Bluetooth не работает, скрипт пытается запустить его, потому что в противном случае, в WinRT не увидите радиомодули Bluetooth. Увы, служба не может быть запущена, если скрипт не запущен от имени администратора. Чтобы сделать это не нужно, вы можете менять тип запуска этой службы на авто.
Теперь какое-то объяснение. Первые три строчки установить параметры в скрипт. Перед началом всерьез, то убедитесь, что Служба поддержки Bluetooth запущена и запустить его, если нет. Затем мы загружаем систему.Время выполнения.Сборка WindowsRuntime так что мы можем использовать WindowsRuntimeSystemExtensions в [.AsTask
](https://msdn.microsoft.com/en-us/library/hh779747(v=vs. 110).aspx) метод, чтобы преобразовать в WinRT-тип задачи (что .Сеть/PowerShell с не'т понял) для .Чистая [задача
](https://msdn.microsoft.com/en-us/library/dd321424(в=против 110).аспн)С. Каждый конкретный метод имеет кучу разных наборов параметров, которые, кажется, путешествие в PowerShell's в разрешении перегрузки, поэтому в следующей строке мы получаем конкретно тот, который берет только задача resultful для WinRT. Затем мы определяем функцию, что мы'будете использовать несколько раз, чтобы извлечь результат соответствующего типа с асинхронной задачи для WinRT. После этого функция's в декларации, мы загрузить два необходимых типов метаданных для WinRT. Остальная часть скрипта-это просто перевод с PowerShell в C# код, который вы написали в ответ; он использует радио
класс WinRT, чтобы найти и настроить радиомодуль Bluetooth.
Бросив искать готовые решения, я обнаружил, что приложения Universal Windows Platform имеют доступ к API радиоуправления.
Поэтому я объединил пример приложения для радиоуправления с приложением, управляемым командной строкой, и результат получился здесь: https://github.com/peci1/RadioControl . Оно опубликовано в Windows Store.
В общем, нельзя просто запустить приложение в фоновом режиме, поэтому сначала нужно запустить графический интерфейс, а затем вызвать его из командной строки, как например
radiocontrol.exe 0 on
radiocontrol.exe Bluetooth off
Основные функции, которые нужны этому приложению, следующие:
using Windows.Devices.Radios;
await Radio.RequestAccessAsync();
var radios = await Radio.GetRadiosAsync();
await radios[0].SetStateAsync(RadioState.On);
Затем вам также нужно добавить возможность Radios в манифест приложения:
<DeviceCapability Name="radios" />
А чтобы разрешить управление из командной строки, нужно переопределить метод protected override async void OnActivated(IActivatedEventArgs args)
в App.xaml.cs и выполнить обработку в ветке следующим образом:
switch (args.Kind)
{
case ActivationKind.CommandLineLaunch:
Этот скрипт для AutoHotkey, кажется, сделать трюк. Я боюсь, сон
есть, но кажется, что окно становится активным, прежде чем он будет готов принять меня клавиши.
SendMode Input
Run, ms-settings:bluetooth
WinWaitActive, Settings
Sleep 300
Send,{Tab}{Space}
WinClose, A
Crossposted в https://stackoverflow.com/q/48700268/308851 чтобы понять, что это сон 300` может быть заменен.
Вот'частичное решение: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\\%'" call disable
, конечно, заставляет переключатель включения/выключения Bluetooth исчезнуть, а диспетчер устройств сообщает Это устройство отключено. (Код 22)
. Достаточно ли этого, чтобы убить радио, я не уверен.
Я не могу найти документацию о том, какие аргументы принимает call
. Думаю, здесь должно быть что-то вроде rfkill
.
Вы можете использовать DevManView, чтобы включить/отключить устройство из командной строки, используя следующий синтаксис:
devmanview /disable <Device Name>
devmanview /enable <Device Name>
Это также позволяет использовать подстановочные знаки с аргументом /use_wildcard
.
Я сделал скрипт, который проверяет значение ключа Рег которым лишь бы быть в месте, если ваше радио Bluetooth был включен. Затем он называет Бен Н'сек скрипта PowerShell выше с правильным параметром для переключения его текущее состояние. Превращает его в переключать ярлык, вместо того, чтобы использовать и выключать по отдельности.
@echo off
FOR /F "skip=2 tokens=2,*" %%A IN ('reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\bthserv\Parameters\BluetoothControlPanelTasks" /v "state"') DO set "VAR=%%B"
if %VAR%==0x1 (goto ON)
Powershell.exe -executionpolicy remotesigned -windowstyle hidden -File ".\bluetooth.ps1" -BluetoothStatus On
goto end
:ON
Powershell.exe -executionpolicy remotesigned -windowstyle hidden -File ".\bluetooth.ps1" -BluetoothStatus Off
:end
В PowerShell командлетов для выполнения именно то, что вы'вновь ищу:
https://gallery.technet.microsoft.com/PowerShell-Device-60d73bb0
Используйте get-устройство для получения списка устройств. Можно передать, что через где-объект, чтобы выбрать устройство, а затем трубу, чтобы отключить устройство и включить устройство.
Подробная Инструкция...
Скачать и распаковать архив.
Запустите PowerShell от имени администратора.
Изменить политику выполнения, если необходимо:
Set-ExecutionPolicy Unrestricted
Импортировать модуль:
Import-Module .\DeviceManagement.psd1
Если вам нужно сузить список устройств, которые можно использовать как сравнить:
Get-Device | Where-Object {$_.Name -like '*bluetooth*'}
Если вы знаете точное имя, которое вы можете использовать -экв ("равно") сравните:
Get-Device | Where-Object {$_.Name -eq 'Martin's Bluetooth Adapter'} | Disable-Device -Confirm:$False
Вытирать руки о штаны.
Выполнение следующей команды из Командной строки (от имени администратора) помогло:
netsh interface set interface name="Bluetooth Network Connection" admin=disabled
Ранее я использовал эту же команду для отключения адаптера Wi-Fi и обнаружил, что она также работает с другими адаптерами в: Панель управления > Сеть и Интернет > Сетевые подключения. Просто измените аргумент "имя" на имя вашего адаптера. Вы также можете включить его снова, изменив последний аргумент на admin=enabled
.