Encender / apagar la radio / adaptador Bluetooth desde cmd / powershell en Windows 10

28

Una tarea tan simple, uno diría, y no he encontrado una solución satisfactoria. Lo que he intentado (con música reproduciéndose a través de un altavoz conectado por Bluetooth para saber realmente el estado de la radio):

  • usando devcon como administrador: devcon disable USB\VID_8087&PID_07DC&REV_0001(que es la identificación HW de mi adaptador Bluetooth) ... requiere reiniciar para funcionar ...
  • usando powershell como administrador: Disable-NetAdapter "Bluetooth Network Connection 3"(que es la traducción del nombre de mi adaptador Bluetooth) ... deshabilita el controlador PAN, pero un altavoz Bluetooth continúa reproduciendo música ...
  • usando net como administrador: net stop bthserv... en realidad no apaga la radio (el altavoz BT continúa reproduciendo música)
  • usando .NET: la página más relevante en MSDN no dice una palabra acerca de cómo encender / apagar el adaptador.
  • usando explorer: ms-settings:bluetootho explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms... abre el panel de configuración de Bluetooth, pero aún tengo que hacer clic en el botón

No puedo creer que Microsoft sea tan ignorante para no proporcionar ese comando ...

Martin Pecka
fuente
Como estas tocando la musica
harrymc
Usando Winamp :)
Martin Pecka
¿Matar a Winamp detiene la música?
harrymc
Por supuesto, ¿por qué no lo haría? Pero la pregunta no se trata de detener la reproducción de música, se trata del control de la radio BT.
Martin Pecka
1
@harrymc Lea la pregunta, por favor. La reproducción de música es solo una forma de detectar si la conexión Bluetooth está activa o no. Lo que realmente me interesa es realmente una forma de deshabilitar / habilitar el adaptador Bluetooth.
Martin Pecka

Respuestas:

21

Esto es desafiante debido a la necesaria interoperación con WinRT, pero es posible en PowerShell puro:

[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

Para usarlo, guárdelo es un archivo PS1, por ejemplo bluetooth.ps1. Si aún no lo ha hecho, siga las instrucciones en la sección Habilitación de scripts de la wiki de etiquetas de PowerShell para habilitar la ejecución de scripts en su sistema. Luego puede ejecutarlo desde un indicador de PowerShell como este:

.\bluetooth.ps1 -BluetoothStatus On

Para desactivar Bluetooth, pasa en su Offlugar.

Para ejecutarlo desde un archivo por lotes:

powershell -command .\bluetooth.ps1 -BluetoothStatus On

Advertencia: si el servicio de soporte de Bluetooth no se está ejecutando, el script intenta iniciarlo porque de lo contrario, WinRT no verá las radios de Bluetooth. Por desgracia, el servicio no se puede iniciar si el script no se ejecuta como administrador. Para que sea innecesario, puede cambiar el tipo de inicio de ese servicio a automático.

Ahora para alguna explicación. Las primeras tres líneas establecen los parámetros que toma el script. Antes de comenzar en serio, nos aseguramos de que el servicio de asistencia Bluetooth se esté ejecutando y lo iniciamos si no. Luego cargamos el System.Runtime.WindowsRuntimeensamblaje para que podamos usar el WindowsRuntimeSystemExtensions.AsTaskmétodo para convertir tareas de estilo WinRT (que .NET / PowerShell no entiende) a .NET Tasks. Ese método en particular tiene una gran cantidad de diferentes conjuntos de parámetros que parecen disparar la resolución de sobrecarga de PowerShell, por lo que en la siguiente línea obtenemos el específico que toma solo una tarea WinRT resultante. Luego definimos una función que usaremos varias veces para extraer un resultado del tipo apropiado de una tarea WinRT asíncrona. Después de la declaración de esa función, cargamos dos tipos necesarios de metadatos de WinRT. El resto del script es más o menos una traducción de PowerShell del código C # que escribió en su respuesta; utiliza la Radioclase WinRT para buscar y configurar la radio Bluetooth.

Ben N
fuente
1
No puede llamar a un método en una expresión de valor nulo. En C: \ Users \ chx \ AppData \ Local \ Microsoft \ WindowsApps \ bluetooth.ps1: 18 char: 1 + Await ($ bluetooth.SetStateAsync ($ BluetoothStatus)) ([Windows.Devices.
chx
@chx ¿Está seguro de que su máquina tiene un adaptador Bluetooth? Si no hay radio Bluetooth, la penúltima línea se establecerá $bluetoothen nula, lo que hará que la penúltima línea produzca ese error.
Ben N
Estoy 100% seguro de que es visible en la aplicación "Configuración" y escucho música de forma inalámbrica y tanto Device Manager como wmic también lo informan.
chx
@chx Hmm, ¿qué obtienes si reemplazas las últimas tres líneas con solo $radios? Eso mostrará la lista de radios que WinRT devolvió.
Ben N
2
¡Listo, funciona! Simplemente no pude compilar una aplicación de escritorio usando esta API, pero cargarla dinámicamente en un script parece ser el camino a seguir. Ahora, compare con rfkill unblock bluetoothLinux :-D
Martin Pecka
5

Después de rendirme para buscar soluciones ya hechas, descubrí que las aplicaciones de la Plataforma universal de Windows tienen acceso a la API de control de radio .

Así que fusioné una aplicación de control de radio de muestra con una aplicación controlada por línea de comandos, y el resultado está aquí: https://github.com/peci1/RadioControl . Está publicado en la Tienda Windows .

En general, no es posible dejar que la aplicación se ejecute en segundo plano, por lo que primero debe iniciar la GUI, y luego puede llamarla desde la línea de comandos como

radiocontrol.exe 0 on
radiocontrol.exe Bluetooth off

Las características principales que necesita esta aplicación son:

using Windows.Devices.Radios;
await Radio.RequestAccessAsync();
var radios = await Radio.GetRadiosAsync();
await radios[0].SetStateAsync(RadioState.On);

Luego, también debe agregar la capacidad de Radios al manifiesto de la aplicación:

<DeviceCapability Name="radios" />

Y para permitir el control desde la línea de comandos, debe anular el método protected override async void OnActivated(IActivatedEventArgs args)en App.xaml.cs y hacer el procesamiento en una rama como esta:

switch (args.Kind)
        {
            case ActivationKind.CommandLineLaunch:
Martin Pecka
fuente
Esta respuesta se adapta mejor a StackOverflow.
harrymc
@MartinPecka Por casualidad, ¿sabe cómo volver a conectar el hardware Bluetooth que se ha desconectado usando Disable/Enable-NetAdapter? superuser.com/questions/1444278/...
JinSnow
3

Este script de Autohotkey parece hacer el truco. SleepAllí me molesta, pero parece que la ventana se activa antes de que esté lista para recibir mis pulsaciones de teclas.

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

Crossposted a /programming//q/48700268/308851 para averiguar con qué Sleep 300podría reemplazarse.

chx
fuente
Esto también podría ser una solución en la mayoría de los casos. También necesitaba agregar un sueño corto después de enviar las pulsaciones de teclas. Y esta solución no funciona si la pantalla está bloqueada. La aplicación universal de Windows que publiqué anteriormente funciona incluso con la pantalla bloqueada.
Martin Pecka
2

Aquí hay una solución parcial: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\%'" call disableciertamente hace que el interruptor de encendido / apagado de Bluetooth desaparezca e informes del Administrador de dispositivos This device is disabled. (Code 22). Si eso es suficiente para matar la radio, no estoy seguro.

No puedo encontrar documentación sobre qué argumentos callacepta. Creo que debería haber algún tipo de rfkillaquí.

chx
fuente
Lo siento, no funciona para mí como lo describe. Para mí, la reproducción de Bluetooth se detiene, pero todos los interruptores bluetooth en el panel de control permanecen activados. Y llamar con enableno reanuda la reproducción de Bluetooth. La documentación sobre la clase PNPEntity está aquí: msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx , pero parece que no hay otros métodos útiles ...
Martin Pecka
1

Puede usar DevManView para habilitar / deshabilitar un dispositivo desde la línea de comandos usando esta sintaxis:

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

También permite el uso de comodines con el /use_wildcardargumento.

rahuldottech
fuente
Devmanview es de hecho una herramienta útil, pero no resuelve mi problema. El problema es que no parece haber un dispositivo que pueda deshabilitar en el administrador de dispositivos para apagar la radio bluetooth.
Martin Pecka
@MartinPecka ¿No ves ninguno de estos? i.stack.imgur.com/UrOuc.png Si no, puede intentar actualizar los controladores ...
rahuldottech
Veo el dispositivo Bluetooth, pero deshabilitarlo no detiene la reproducción, probablemente porque el sistema necesita reiniciarse para que realmente se desactive (como se indica en la pregunta original).
Martin Pecka
0

Powershell tiene cmdlets para hacer exactamente lo que estás buscando:

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

Use Get-Device para obtener una lista de los dispositivos. Puede canalizarlo a través de where-object para elegir su dispositivo y luego canalizarlo a Disable-Device o Enable-Device.

Instrucciones detalladas...

Descargue y descomprima el archivo.

Inicie un PowerShell como administrador.

Cambie la política de ejecución si es necesario:

Set-ExecutionPolicy Unrestricted

Importar el módulo:

Import-Module .\DeviceManagement.psd1

Si necesita reducir la lista de dispositivos, puede usar una comparación similar:

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

Si conoce el nombre exacto, puede usar una comparación -eq (igual):

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

Limpie las manos en los pantalones.

apocalipsis
fuente
Esto desactivará el dispositivo USB en lugar de solo la radio. wmicpuede hacer esto también, al menos eso creo.
chx
La pregunta no preguntaba cómo deshabilitar la radio pero no el adaptador. ¿Por qué la distinción? Si me puede dar una buena razón, consideraré cavar por usted, pero respondí la pregunta que se hizo "Lo que realmente me interesa es realmente una forma de deshabilitar / habilitar el adaptador Bluetooth. - Martin Pecka 5 de febrero en 9:31 "
apocalipsis
Lo siento, ¿cuál es la diferencia entre el adaptador y la radio? Considero que estos dos términos son equivalentes. Hay una gran cantidad de dispositivos de software que proporciona esta cosa de HW, y tienes razón, esta pregunta no se trata de ellos.
Martin Pecka
Además, tanto este como el script PS de 2012 de Ricardo Mendes no funcionan en mi Win 10 1709 de 64 bits, como se menciona en sus comentarios. Ambos terminan con error Disable-Device : Error calling SetupDiCallClassInstaller. Los ejecuto como administrador y con una política de ejecución sin restricciones.
Martin Pecka
0

Hice un script por lotes que verifica un valor de clave reg que solo estaría en su lugar si su radio bluetooth estuviera habilitada. Luego llama al script de PowerShell de Ben N anterior con el parámetro correcto para cambiar su estado actual. Lo convierte en un acceso directo de palanca, en lugar de tener que usarlo por separado.

@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
007craft
fuente
-1

Ejecutar el siguiente comando desde el símbolo del sistema (como administrador) hizo el truco:

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

Anteriormente había usado el mismo comando para deshabilitar mi adaptador Wi-Fi, y descubrí que también funcionaba con los otros adaptadores en: Panel de control> Red e Internet> Conexiones de red. Simplemente cambie el argumento "nombre" al nombre de su adaptador. También puede habilitarlo nuevamente cambiando el último argumento a admin=enabled.

Micah Vertal
fuente
1
Esto también parece deshabilitar los controladores PAN, pero no apaga el dispositivo de radio en sí mismo (en el panel de control, Bluetooth todavía se informa como "encendido").
Martin Pecka
Verificado ahora por la prueba de repro de bluetooth, no apaga el bluetooth.
Martin Pecka
Lo siento @ peci1, no entendí tu pregunta. Anteriormente había estado mirando preguntas relacionadas con la desactivación de Bluetooth e interpreté su pregunta de la misma manera. Entonces, ¿su objetivo es apagar (cortar la alimentación) del dispositivo Bluetooth? Investigaré un poco y te haré saber si encuentro algo.
Micah Vertal
@ peci1 ¿ sería útil este enlace ?
Micah Vertal
No, no lo hace. Se trata de dispositivos USB, no de Bluetooth. Y el Cmdlet de administración de dispositivos vinculado tampoco funciona.
Martin Pecka