Attiva / disattiva la radio / adattatore Bluetooth da cmd / powershell in Windows 10


28

Un compito così semplice, si direbbe, e non ho trovato una soluzione soddisfacente. Cosa ho provato (con la riproduzione di musica attraverso un altoparlante Bluetooth per conoscere veramente lo stato della radio):

  • usando devcon come admin: devcon disable USB\VID_8087&PID_07DC&REV_0001(che è l'ID HW del mio adattatore Bluetooth) ... richiede il riavvio per funzionare ...
  • usando powershell come admin: Disable-NetAdapter "Bluetooth Network Connection 3"(che è la traduzione del nome del mio adattatore Bluetooth) ... disabilita il driver PAN, ma un altoparlante Bluetooth continua a riprodurre musica ...
  • usando net come admin: net stop bthserv... in realtà non spegne la radio (l'altoparlante BT continua a riprodurre musica)
  • usando .NET: la pagina più rilevante su MSDN non dice una parola sull'accensione / spegnimento dell'adattatore.
  • usando explorer: ms-settings:bluetootho explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms... apre il pannello delle impostazioni Bluetooth, ma devo ancora fare clic sull'interruttore

Non posso credere che Microsoft sarebbe così ignorante da non fornire un tale comando ...


Come stai suonando la musica?
harrymc,

Usando Winamp :)
Martin Pecka,

Uccidere Winamp ferma la musica?
harrymc,

Certo, perché non dovrebbe? Ma la domanda non riguarda l'interruzione della riproduzione musicale, si tratta del controllo della radio BT.
Martin Pecka,

1
@harrymc Leggi la domanda, per favore. La riproduzione musicale è solo un modo per rilevare se la connessione Bluetooth è attiva o meno. Quello che mi interessa davvero è davvero un modo per disabilitare / abilitare l'adattatore Bluetooth.
Martin Pecka,

Risposte:


21

Questo è impegnativo a causa dell'interazione necessaria con WinRT, ma è possibile in 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

Per usarlo, salvarlo è un file PS1, ad es bluetooth.ps1. Se non lo hai già fatto, segui le istruzioni nella sezione Abilitazione degli script del wiki del tag PowerShell per abilitare l'esecuzione degli script sul tuo sistema. Quindi è possibile eseguirlo da un prompt di PowerShell in questo modo:

.\bluetooth.ps1 -BluetoothStatus On

Per disattivare il Bluetooth, passa Offinvece.

Per eseguirlo da un file batch:

powershell -command .\bluetooth.ps1 -BluetoothStatus On

Avvertenza: se il servizio di supporto Bluetooth non è in esecuzione, lo script tenta di avviarlo perché altrimenti WinRT non vedrà le radio Bluetooth. Purtroppo, il servizio non può essere avviato se lo script non è in esecuzione come amministratore. Per rendere ciò non necessario, è possibile modificare il tipo di avvio di quel servizio su automatico.

Ora per qualche spiegazione. Le prime tre righe stabiliscono i parametri dello script. Prima di iniziare sul serio, ci assicuriamo che il servizio di supporto Bluetooth sia in esecuzione e avviarlo in caso contrario. Carichiamo quindi l' System.Runtime.WindowsRuntimeassembly in modo da poter utilizzare il WindowsRuntimeSystemExtensions.AsTaskmetodo per convertire le attività in stile WinRT (che .NET / PowerShell non capisce) in .NET Task. Questo particolare metodo ha un carico di diversi set di parametri che sembrano inciampare nella risoluzione di sovraccarico di PowerShell, quindi nella riga successiva abbiamo quello specifico che prende solo un'attività WinRT risultante. Quindi definiamo una funzione che useremo più volte per estrarre un risultato del tipo appropriato da un'attività WinRT asincrona. A seguito della dichiarazione di tale funzione, vengono caricati due tipi necessari dai metadati WinRT. Il resto dello script è praticamente solo una traduzione PowerShell del codice C # che hai scritto nella tua risposta; utilizza la Radioclasse WinRT per trovare e configurare la radio Bluetooth.


1
Non è possibile chiamare un metodo su un'espressione a valore null. A C: \ Users \ chx \ AppData \ Local \ Microsoft \ WindowsApps \ bluetooth.ps1: 18 char: 1 + Await ($ bluetooth.SetStateAsync ($ BluetoothStatus)) ([Windows.Devices.
chx

@chx Sei sicuro che la tua macchina abbia un adattatore Bluetooth? Se non è presente la radio Bluetooth, la penultima riga verrà impostata $bluetoothsu null, il che causerà la penultima riga a produrre quell'errore.
Ben N

Sono sicuro al 100% che sia visibile nell'app "Impostazioni" e ascolto la musica in modalità wireless e sia Device Manager che Wmic lo segnalano.
chx,

@chx Hmm, cosa ottieni se sostituisci le ultime tre righe con solo $radios? Ciò mostrerà l'elenco delle radio restituite da WinRT.
Ben N

2
Intelligente, funziona! Non sono riuscito a compilare un'app desktop usando questa API, ma caricarla dinamicamente in uno script sembra essere la strada da percorrere. Ora, confronta con rfkill unblock bluetoothsu Linux :-D
Martin Pecka,

5

Dopo aver rinunciato a cercare soluzioni già pronte, ho scoperto che le app della piattaforma Windows universale hanno accesso all'API di controllo radio .

Così ho unito un'app di controllo radio di esempio con un'app controllata da riga di comando e il risultato è qui: https://github.com/peci1/RadioControl . È pubblicato su Windows Store .

In generale, non è possibile solo far funzionare l'app in background, quindi devi prima avviare la GUI e quindi puoi chiamarla dalla riga di comando come

radiocontrol.exe 0 on
radiocontrol.exe Bluetooth off

Le funzionalità principali di cui ha bisogno questa app sono:

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

Quindi devi anche aggiungere la funzionalità Radio al manifest dell'app:

<DeviceCapability Name="radios" />

E per consentire il controllo dalla riga di comando, è necessario sovrascrivere il metodo protected override async void OnActivated(IActivatedEventArgs args)in App.xaml.cs ed eseguire l'elaborazione in un ramo come questo:

switch (args.Kind)
        {
            case ActivationKind.CommandLineLaunch:

Questa risposta si adatta meglio a StackOverflow.
harrymc,

@MartinPecka Per caso, sai come riconnettere l'hardware Bluetooth che è stato disconnesso utilizzando Disable/Enable-NetAdapter? superuser.com/questions/1444278/…
JinSnow il

3

Questo script Autohotkey sembra fare il trucco. Sono infastidito da Sleeplì, ma sembra che la finestra diventi attiva prima che sia pronta a ricevere i miei tasti.

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

Crossposted su /programming//q/48700268/308851 per capire con cosa Sleep 300potrebbe essere sostituito.


Questa potrebbe anche essere una soluzione nella maggior parte dei casi. Ho anche dovuto aggiungere un breve sonno dopo aver inviato i tasti. E questa soluzione non funziona se lo schermo è bloccato. L'app di Windows universale che ho pubblicato sopra funziona anche con lo schermo bloccato.
Martin Pecka,

2

Ecco una soluzione parziale: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\%'" call disablecertamente scompare l'interruttore Bluetooth On / Off e Device Manager riporta This device is disabled. (Code 22). Se sia abbastanza per uccidere la radio, non ne sono sicuro.

Non riesco a trovare la documentazione su quali argomenti callaccetta. Penso che dovrebbe esserci una sorta di rfkillqui.


Mi dispiace, non funziona per me come lo descrivi. Per me, la riproduzione Bluetooth si interrompe, ma tutti gli interruttori bluetooth nel pannello di controllo rimangono attivi. E la chiamata con enablenon riprende la riproduzione Bluetooth. La documentazione sulla classe PNPEntity è qui: msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx , ma non sembrano esserci altri metodi utili ...
Martin Pecka

1

È possibile utilizzare DevManView per abilitare / disabilitare un dispositivo dalla riga di comando utilizzando questa sintassi:

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

Consente inoltre l'uso di caratteri jolly con l' /use_wildcardargomento.


Devmanview è davvero uno strumento utile, ma non risolve il mio problema. Il problema è che non sembra esserci un dispositivo che potresti disabilitare in Gestione dispositivi per spegnere la radio bluetooth.
Martin Pecka,

@MartinPecka Non vedi nessuno di questi? i.stack.imgur.com/UrOuc.png Altrimenti, potresti voler provare ad aggiornare i driver ...
rahuldottech,

Vedo il dispositivo Bluetooth, ma disabilitarlo non interrompe la riproduzione, probabilmente perché il sistema deve essere riavviato perché sia ​​realmente disabilitato (come indicato nella domanda originale).
Martin Pecka,

0

Powershell ha cmdlet per fare esattamente quello che stai cercando:

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

Utilizzare Get-Device per ottenere un elenco dei dispositivi. È possibile reindirizzare attraverso Where-Object per selezionare il dispositivo e quindi reindirizzarlo su Disable-Device o Enable-Device.

Istruzioni dettagliate ...

Scarica e decomprimi il file.

Avvia una PowerShell come amministratore.

Modificare la politica di esecuzione se necessario:

Set-ExecutionPolicy Unrestricted

Importa il modulo:

Import-Module .\DeviceManagement.psd1

Se hai bisogno di restringere l'elenco dei dispositivi puoi usare un confronto simile:

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

Se conosci il nome esatto puoi usare un confronto -eq (uguale a):

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

Pulisci le mani sui pantaloni.


Questo disabiliterà il dispositivo USB anziché solo la radio. wmicposso fare anche questo, almeno io la penso così.
chx,

La domanda non chiedeva come disabilitare la radio ma non l'adattatore. Perché la distinzione? Se puoi darmi una buona ragione, prenderò in considerazione l'idea di scavare per te, ma ho risposto alla domanda che mi è stata posta "Quello che mi interessa davvero è davvero un modo per disabilitare / abilitare l'adattatore Bluetooth. - Martin Pecka, 5 febbraio a 9:31 "
apocalisse

Mi dispiace, qual è la differenza tra adattatore e radio? Considero questi due termini equivalenti. C'è un sacco di dispositivi software forniti da questa cosa HW, e hai ragione questa domanda non riguarda loro.
Martin Pecka,

Inoltre, sia questo che lo script PS 2012 di Ricardo Mendes non funzionano al mio Win 10 1709 64 bit, come menzionato nei loro commenti. Entrambi finiscono con un errore Disable-Device : Error calling SetupDiCallClassInstaller. Li eseguo come amministratore e con una politica di esecuzione senza restrizioni.
Martin Pecka,

0

Ho creato uno script batch che controlla un valore chiave reg che sarebbe presente solo se la tua radio bluetooth fosse abilitata. Quindi chiama lo script PowerShell di Ben N sopra con il parametro corretto per cambiare il suo stato attuale. Trasforma in un collegamento a levetta, piuttosto che doverlo accendere e spegnere separatamente.

@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

L'esecuzione del seguente comando dal prompt dei comandi (come amministratore) ha funzionato:

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

In precedenza avevo usato lo stesso comando per disabilitare il mio adattatore Wi-Fi e ho scoperto che funzionava anche con gli altri adattatori in: Pannello di controllo> Rete e Internet> Connessioni di rete. Basta cambiare l'argomento "name" con il nome della scheda. Puoi anche riattivarlo modificando l'ultimo argomento in admin=enabled.


1
Questo sembra anche disabilitare solo i driver PAN, ma non spegne il dispositivo radio stesso (nel pannello di controllo, il Bluetooth è ancora segnalato come "attivo").
Martin Pecka,

Verificato ora dal test di riproduzione bluetooth, non disattiva il bluetooth.
Martin Pecka,

Mi dispiace @ peci1, ho frainteso la tua domanda. In precedenza avevo esaminato le domande relative alla disabilitazione del Bluetooth e interpretato la tua domanda come la stessa. Quindi il tuo obiettivo è spegnere (interrompere l'alimentazione) il dispositivo Bluetooth? Cercherò un po 'di ricerche e ti farò sapere se trovo qualcosa.
Micah Vertal,

@ peci1 questo link sarebbe utile?
Micah Vertal,

No non lo fa. Si tratta di USB, non di dispositivi Bluetooth. E neanche il Cmdlet di Device Management collegato funziona.
Martin Pecka,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.