web-dev-qa-db-fra.com

Activer/désactiver Bluetooth radio/adaptateur à partir de cmd/powershell dans Windows 10

Une tâche si simple, dirait-on, et je n’ai pas trouvé de solution satisfaisante. Ce que j'ai essayé (avec de la musique diffusée via un haut-parleur connecté en Bluetooth pour connaître vraiment l'état de la radio):

  • en utilisant devcon en tant qu'administrateur: devcon disable USB\VID_8087&PID_07DC&REV_0001 (qui est l'identifiant matériel de mon adaptateur Bluetooth) ... nécessite un redémarrage pour fonctionner ...
  • using powershell en tant qu'administrateur: Disable-NetAdapter "Bluetooth Network Connection 3" (qui traduit le nom de mon adaptateur Bluetooth) ... désactive le pilote PAN, mais un haut-parleur Bluetooth continue de lire de la musique ...
  • utiliser net comme administrateur: net stop bthserv... n'éteint pas la radio (le haut-parleur BT continue de jouer de la musique)
  • using .NET: La page la plus pertinente de MSDN ne dit pas un mot sur l'activation/la désactivation de l'adaptateur.
  • en utilisant Explorer: ms-settings:bluetooth ou Explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms... ouvre le panneau de configuration Bluetooth, mais je dois quand même cliquer sur la bascule

Je ne peux pas croire que Microsoft serait si ignorant de ne pas fournir une telle commande ...

24
Martin Pecka

C’est un défi en raison de l’interopérabilité nécessaire avec WinRT, mais il est possible dans PowerShell pur:

[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

Pour l'utiliser, enregistrez-le dans un fichier PS1, par exemple. bluetooth.ps1. Si vous ne l'avez pas déjà fait, suivez les instructions de la section Activation des scripts de le wiki de balise PowerShell pour activer l'exécution de scripts sur votre système. Vous pouvez ensuite l'exécuter à partir d'une invite PowerShell comme ceci:

.\bluetooth.ps1 -BluetoothStatus On

Pour désactiver le Bluetooth, transmettez plutôt Off.

Pour l'exécuter à partir d'un fichier de commandes:

powershell -command .\bluetooth.ps1 -BluetoothStatus On

Avertissement: Si le service de support Bluetooth n'est pas en cours d'exécution, le script tente de le démarrer car sinon, WinRT ne verra pas les radios Bluetooth. Hélas, le service ne peut pas être démarré si le script ne s'exécute pas en tant qu'administrateur. Pour rendre cela inutile, vous pouvez changer le type de démarrage de ce service en automatique.

Maintenant pour quelques explications. Les trois premières lignes établissent les paramètres du script. Avant de commencer sérieusement, nous nous assurons que le service d'assistance Bluetooth est en cours d'exécution et le démarrons sinon. Nous chargeons ensuite l'assembly System.Runtime.WindowsRuntime afin de pouvoir utiliser la méthode WindowsRuntimeSystemExtensions.AsTask pour convertir les tâches de style WinRT (que .NET/PowerShell ne comprend pas) en .NET Task s. Cette méthode particulière comporte une série de paramètres différents qui semblent surcharger la résolution de surcharge de PowerShell. Ainsi, à la ligne suivante, nous obtenons celle qui prend uniquement une tâche WinRT résultante. Ensuite, nous définissons une fonction que nous utiliserons plusieurs fois pour extraire un résultat du type approprié d’une tâche WinRT asynchrone. Suite à la déclaration de cette fonction, nous chargeons deux types nécessaires à partir des métadonnées WinRT . Le reste du script est en gros une traduction PowerShell du code C # que vous avez écrit dans votre réponse. il utilise la classe Radio WinRT pour rechercher et configurer la radio Bluetooth.

15
Ben N

Après avoir abandonné la recherche de solutions toutes faites, j'ai découvert que les applications de la plate-forme Windows universelle avaient accès à la API de contrôle radio .

J'ai donc fusionné un exemple d'application de contrôle radio avec une application contrôlée par ligne de commande. Le résultat est ici: https://github.com/peci1/RadioControl C'est publié sur le Windows Store .

En général, il n'est pas possible de laisser simplement l'application s'exécuter en arrière-plan. Vous devez donc d'abord lancer l'interface graphique, puis l'appeler à partir de la ligne de commande, comme

radiocontrol.exe 0 on
radiocontrol.exe Bluetooth off

Les principales fonctionnalités de cette application sont les suivantes:

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

Ensuite, vous devez également ajouter la fonctionnalité Radios au manifeste de l'application:

<DeviceCapability Name="radios" />

Et pour permettre le contrôle depuis la ligne de commande, vous devez redéfinir la méthode protected override async void OnActivated(IActivatedEventArgs args) dans App.xaml.cs et effectuer le traitement dans une branche comme celle-ci:

switch (args.Kind)
        {
            case ActivationKind.CommandLineLaunch:
3
Martin Pecka

Ce script Autohotkey semble faire l'affaire. La Sleep me gêne, mais il semble que la fenêtre s'active avant d'être prête à recevoir mes touches.

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

Répondez à https://stackoverflow.com/q/48700268/308851 pour savoir en quoi ce Sleep 300 pourrait être remplacé.

2
chx

Voici une solution partielle: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\%'" call disable fait certainement disparaître le commutateur Bluetooth On/Off et le Gestionnaire de périphériques indique This device is disabled. (Code 22). Que ce soit suffisant pour tuer la radio, je ne suis pas sûr.

Je suis incapable de trouver de la documentation sur les arguments que call accepte. Je pense qu'il devrait y avoir une sorte de rfkill ici.

1
chx

Powershell a des applets de commande pour faire exactement ce que vous recherchez:

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

Utilisez Get-Device pour obtenir une liste des périphériques. Vous pouvez diriger cet objet à travers where-object pour sélectionner votre périphérique, puis le diriger vers Disable-Device ou Enable-Device.

Instructions détaillées...

Téléchargez et décompressez le fichier.

Démarrer un PowerShell en tant qu'administrateur.

Changer la politique d'exécution si nécessaire:

Set-ExecutionPolicy Unrestricted

Importer le module:

Import-Module .\DeviceManagement.psd1

Si vous avez besoin de réduire la liste des appareils, vous pouvez utiliser une comparaison semblable à celle-ci:

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

Si vous connaissez le nom exact, vous pouvez utiliser une comparaison -eq (equals):

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

Essuyez les mains sur les pantalons.

0
apocalysque

Vous pouvez utiliser DevManView pour activer/désactiver un périphérique à partir de la ligne de commande en utilisant cette syntaxe:

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

Il permet également l'utilisation de caractères génériques avec l'argument /use_wildcard.

0
rahuldottech

J'ai créé un script de lot qui vérifie une valeur de clé de registre qui ne serait en place que si votre radio Bluetooth était activée. Il appelle ensuite le script powershell de Ben N ci-dessus avec le paramètre correct pour changer son état actuel. Le transforme en un raccourci à bascule, plutôt que d'avoir à utiliser on et off séparément.

@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
0
007craft