Включение / выключение радио / адаптера Bluetooth из cmd / powershell в Windows 10


28

Такая простая задача, можно сказать, и я не нашел удовлетворительного решения. Что я пробовал (с музыкой, воспроизводимой через Bluetooth-подключенный динамик, чтобы действительно знать состояние радио):

  • используя devcon в качестве администратора: devcon disable USB\VID_8087&PID_07DC&REV_0001(это HW ID моего адаптера Bluetooth) ... требуется перезагрузка для работы ...
  • используя powershell в качестве администратора: Disable-NetAdapter "Bluetooth Network Connection 3"(это перевод названия моего адаптера Bluetooth) ... он отключает драйвер PAN, но динамик Bluetooth продолжает воспроизводить музыку ...
  • используя net как admin: net stop bthserv... на самом деле радио не выключается (динамик BT продолжает воспроизводить музыку)
  • Использование .NET: на самой релевантной странице MSDN не сказано ни слова о включении / выключении адаптера.
  • используя проводник: ms-settings:bluetoothили explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms... открывает панель настроек Bluetooth, но мне все равно нужно нажать на переключатель

Я не могу поверить, что Microsoft так невежественна, чтобы не предоставлять такую ​​команду ...


Как ты играешь музыку?
Harrymc

Использование Winamp :)
Мартин Пека

Остановка музыки убивает Winamp?
Harrymc

Конечно, почему бы и нет? Но вопрос не в том, чтобы остановить воспроизведение музыки, а в том, чтобы управлять радио BT.
Мартин Пека

1
@harrymc Прочтите вопрос, пожалуйста. Воспроизведение музыки - это просто способ определить, живое соединение Bluetooth или нет. Что меня действительно интересует, так это способ отключить / включить адаптер Bluetooth.
Мартин Пека

Ответы:


21

Это сложно из-за необходимости взаимодействия с 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.ps1. Если вы этого еще не сделали, следуйте инструкциям в разделе «Включение сценариев» вики-тега PowerShell, чтобы включить выполнение сценариев в вашей системе. Затем вы можете запустить его из командной строки PowerShell следующим образом:

.\bluetooth.ps1 -BluetoothStatus On

Чтобы выключить Bluetooth, пройдите Offвместо.

Чтобы запустить его из командного файла:

powershell -command .\bluetooth.ps1 -BluetoothStatus On

Предостережение: если служба поддержки Bluetooth не запущена, скрипт пытается запустить ее, потому что в противном случае WinRT не увидит радио Bluetooth. Увы, сервис не может быть запущен, если скрипт не работает от имени администратора. Чтобы сделать это ненужным, вы можете изменить тип запуска этой службы на автоматический.

Теперь для некоторого объяснения. Первые три строки устанавливают параметры, которые принимает скрипт. Прежде чем начать всерьез, мы должны убедиться, что служба поддержки Bluetooth работает, и запустить ее, если нет. Затем мы загружаем System.Runtime.WindowsRuntimeсборку, чтобы можно было использовать WindowsRuntimeSystemExtensions.AsTaskметод для преобразования задач в стиле WinRT (которые .NET / PowerShell не понимает) в .NET Task. Этот конкретный метод имеет множество различных наборов параметров, которые, кажется, приводят к снижению разрешения перегрузки PowerShell, поэтому в следующей строке мы получим конкретный метод, который выполняет только результативную задачу WinRT. Затем мы определяем функцию, которую будем использовать несколько раз, чтобы извлечь результат соответствующего типа из асинхронной задачи WinRT. После объявления этой функции мы загружаем два необходимых типа из метаданных WinRT, Остальная часть сценария в значительной степени является просто переводом PowerShell кода C #, который вы написали в своем ответе; он использует Radioкласс WinRT для поиска и настройки радиомодуля Bluetooth.


1
Вы не можете вызвать метод для выражения с нулевым значением. В C: \ Users \ chx \ AppData \ Local \ Microsoft \ WindowsApps \ bluetooth.ps1: 18 char: 1 + Await ($ bluetooth.SetStateAsync ($ BluetoothStatus))) ([Windows.Devices.
chx

@chx Вы уверены, что на вашей машине есть адаптер Bluetooth? Если Bluetooth-радио отсутствует, строка с третьей по последнюю станет $bluetoothнулевой, что приведет к появлению этой ошибки со второй по последнюю строку.
Бен N

Я на 100% уверен, что это видно в приложении «Настройки», и я слушаю музыку по беспроводной связи, и диспетчер устройств и wmic также сообщают об этом.
СНХ

@chx Хм, что ты получишь, если заменишь последние три строки просто $radios? Это покажет список радиостанций, которые возвратил WinRT.
Бен N

2
Умно, это работает! Я просто не смог скомпилировать настольное приложение, используя этот API, но загрузка динамически в сценарии, похоже, является подходящим вариантом. Теперь сравните с rfkill unblock bluetoothLinux :-D
Мартин Пека

5

Отказавшись от поиска готовых решений, я обнаружил, что приложения универсальной платформы Windows имеют доступ к API-интерфейсу радиоуправления .

Поэтому я объединил пример приложения для управления радио с приложением, управляемым из командной строки, и результат здесь: https://github.com/peci1/RadioControl . Он опубликован в Магазине Windows .

В общем случае невозможно просто запустить приложение в фоновом режиме, поэтому сначала необходимо запустить графический интерфейс, а затем вызвать его из командной строки, например

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:

Этот ответ лучше подходит для StackOverflow.
Harrymc

@MartinPecka Случайно, вы знаете, как повторно подключить оборудование Bluetooth, которое было отключено с помощью Disable/Enable-NetAdapter? superuser.com/questions/1444278/…
JinSnow

3

Этот скрипт Autohotkey, кажется, делает свое дело. Меня это беспокоит, Sleepно кажется, что окно становится активным, прежде чем оно будет готово для получения моих нажатий клавиш.

SendMode Input
Run, ms-settings:bluetooth
WinWaitActive, Settings
Sleep 300
Send,{Tab}{Space}
WinClose, A

Перейдите на /programming//q/48700268/308851, чтобы выяснить, чем это Sleep 300можно заменить.


Это также может быть решением в большинстве случаев. Мне нужно было также добавить короткий сон после отправки нажатий клавиш. И это решение не работает, если экран заблокирован. Приложение Universal для Windows, которое я разместил выше, работает даже с заблокированным экраном.
Мартин Пека

2

Вот частичное решение: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\%'" call disableбезусловно, исчезает выключатель Bluetooth On / Off, и диспетчер устройств сообщает This device is disabled. (Code 22). Достаточно ли этого, чтобы убить радио, я не уверен.

Я не могу найти документацию о том, какие аргументы callпринимает. Я думаю, что здесь должно быть что-то вроде rfkill.


Извините, у меня не работает, как вы это описываете. Для меня воспроизведение по Bluetooth останавливается, но все переключатели bluetooth на панели управления остаются включенными. И вызов с enableне возобновляет воспроизведение Bluetooth. Документация по классу PNPEntity находится здесь: msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx , но никаких других полезных методов там нет ...
Мартин Пека,

1

Вы можете использовать DevManView для включения / выключения устройства из командной строки, используя следующий синтаксис:

devmanview /disable <Device Name>   
devmanview /enable <Device Name>    

Это также позволяет использовать подстановочные знаки с /use_wildcardаргументом.


Devmanview действительно полезный инструмент, но он не решает мою проблему. Проблема в том, что, похоже, нет устройства, которое можно отключить в диспетчере устройств, чтобы отключить Bluetooth-радио.
Мартин Пека

@MartinPecka Вы не видите ничего из этого? i.stack.imgur.com/UrOuc.png Если нет, вы можете попробовать обновить драйверы ...
rahuldottech

Я вижу устройство Bluetooth, но отключение его не останавливает воспроизведение - возможно, потому, что система должна быть перезапущена, чтобы оно действительно отключилось (как указано в исходном вопросе).
Мартин Пека

0

В Powershell есть командлеты для выполнения именно того, что вы ищете:

https://gallery.technet.microsoft.com/PowerShell-Device-60d73bb0

Используйте Get-Device, чтобы получить список устройств. Вы можете передать это через where-object, чтобы выбрать ваше устройство, а затем передать это Disable-Device или Enable-Device.

Подробные инструкции ...

Загрузите и разархивируйте файл.

Запустите PowerShell как администратор.

Измените политику выполнения при необходимости:

Set-ExecutionPolicy Unrestricted

Импортируйте модуль:

Import-Module .\DeviceManagement.psd1

Если вам нужно сузить список устройств, вы можете использовать сравнение:

Get-Device | Where-Object {$_.Name -like '*bluetooth*'}

Если вы знаете точное имя, вы можете использовать -eq (равно) сравнить:

Get-Device | Where-Object {$_.Name -eq 'Martin's Bluetooth Adapter'} | Disable-Device -Confirm:$False

Протрите руки на штаны.


Это отключит USB-устройство, а не только радио. wmicможет сделать это тоже, по крайней мере, я так думаю.
СНХ

Вопрос не спрашивал, как отключить радио, а не адаптер. Почему различие? Если вы можете дать мне вескую причину, я подумаю о копании для вас, но я ответил на вопрос, который был задан: «Что меня действительно интересует, так это действительно способ отключить / включить адаптер Bluetooth» - Мартин Пека, 5 февраля, 9:31 "
апокалипсис

Извините, в чем разница между адаптером и радио? Я считаю эти два термина эквивалентными. Это большое количество программных устройств, которые предоставляет HW, и вы правы, этот вопрос не о них.
Мартин Пека

Более того, как этот сценарий, так и сценарий PS 2012 года от Рикардо Мендеса не работают на моем Win 10 1709 64bit, как упоминается в их комментариях. Оба заканчиваются ошибкой Disable-Device : Error calling SetupDiCallClassInstaller. Я запускаю их как администратор и с неограниченной политикой исполнения.
Мартин Пека

0

Я сделал пакетный скрипт, который проверяет значение ключа reg, которое будет доступно только в том случае, если ваше радио Bluetooth было включено. Затем он вызывает приведенный выше скрипт powershell от Ben N с правильным параметром для переключения его текущего состояния. Превращает его в ярлык переключения, вместо того, чтобы использовать его отдельно или выключать.

@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

-1

Выполнение следующей команды из командной строки (как администратор) сделало свое дело:

netsh interface set interface name="Bluetooth Network Connection" admin=disabled

Ранее я использовал ту же команду для отключения моего адаптера Wi-Fi и обнаружил, что она также работает с другими адаптерами в: Панель управления> Сеть и Интернет> Сетевые подключения. Просто измените аргумент «name» на имя вашего адаптера. Вы также можете включить его снова, изменив последний аргумент на admin=enabled.


1
Это также, кажется, просто отключает драйверы PAN, но не отключает само радиоустройство (на панели управления Bluetooth по-прежнему отображается как «включено»).
Мартин Пецка,

Проверено сейчас тестом Bluetooth Repro, не отключает Bluetooth.
Мартин

Прости @ peci1, я неправильно понял твой вопрос. Ранее я рассматривал вопросы, связанные с отключением Bluetooth, и интерпретировал ваш вопрос так же. Итак, ваша цель - отключить (отключить питание) устройство Bluetooth? Я немного исследую и сообщу, найду ли я что-нибудь.
Мика Верталь

@ peci1 эта ссылка будет полезна вообще?
Мика Верталь

Нет. Это касается USB, а не устройств Bluetooth. И связанный командлет управления устройствами тоже не работает.
Мартин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.