it-swarm.com.de

Ein-/Ausschalten des Bluetooth-Radios/Adapters von cmd/powershell in Windows 10

Eine so einfache Aufgabe, würde man sagen, und ich habe keine befriedigende Lösung gefunden. Was ich versucht habe (mit Musik über einen Bluetooth-verbundenen Lautsprecher, um den Zustand des Radios wirklich zu kennen):

  • mit devcon als admin: devcon disable USB\VID_8087&PID_07DC&REV_0001 (das ist die HW-ID meines Bluetooth-Adapters) ... erfordert einen Neustart, um zu funktionieren ...
  • verwenden von Powershell als Administrator: Disable-NetAdapter "Bluetooth Network Connection 3" (das ist die Übersetzung des Namens meines Bluetooth-Adapters) ... deaktiviert den PAN -Treiber, aber ein Bluetooth-Lautsprecher spielt weiterhin Musik ab ...
  • verwenden des Netzes als Administrator: net stop bthserv... schaltet das Radio nicht aus (BT-Lautsprecher spielt weiterhin Musik ab)
  • verwenden von .NET: Die relevanteste Seite in MSDN sagt kein Wort über das Ein- und Ausschalten des Adapters.
  • mit dem Explorer: ms-settings:bluetooth oder Explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms... wird das Bluetooth-Einstellungsfeld geöffnet, aber ich muss immer noch auf den Umschalter klicken

Ich kann nicht glauben, dass Microsoft so unwissend wäre, einen solchen Befehl nicht zu erteilen ...

24
Martin Pecka

Dies ist aufgrund der erforderlichen Interoperation mit WinRT eine Herausforderung, aber in reiner PowerShell ist Folgendes möglich:

[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

Speichern Sie es als PS1-Datei, z. bluetooth.ps1. Wenn Sie dies noch nicht getan haben, befolgen Sie die Anweisungen im Abschnitt zum Aktivieren von Skripten in dem PowerShell-Tag-Wiki , um die Ausführung von Skripten auf Ihrem System zu aktivieren. Dann können Sie es von einer PowerShell-Eingabeaufforderung wie folgt ausführen:

.\bluetooth.ps1 -BluetoothStatus On

Um Bluetooth zu deaktivieren, übergeben Sie stattdessen Off.

So führen Sie es aus einer Batchdatei aus:

powershell -command .\bluetooth.ps1 -BluetoothStatus On

Warnung: Wenn der Bluetooth-Supportdienst nicht ausgeführt wird, versucht das Skript, ihn zu starten, da WinRT andernfalls keine Bluetooth-Funkgeräte erkennt. Leider kann der Dienst nicht gestartet werden, wenn das Skript nicht als Administrator ausgeführt wird. Um dies unnötig zu machen, können Sie den Starttyp dieses Dienstes in "Automatisch" ändern.

Nun zur Erklärung. Die ersten drei Zeilen legen die Parameter fest, die das Skript verwendet. Bevor wir ernsthaft beginnen, stellen wir sicher, dass der Bluetooth-Support-Dienst ausgeführt wird, und starten ihn, falls nicht. Anschließend laden wir die Assembly System.Runtime.WindowsRuntime, sodass wir mit der Methode WindowsRuntimeSystemExtensions.AsTask Aufgaben im WinRT-Stil (die .NET/PowerShell nicht versteht) in .NET Task s konvertieren können. Diese bestimmte Methode verfügt über eine Schiffsladung verschiedener Parametersätze, die die Überlastungsauflösung von PowerShell auszulösen scheinen. In der nächsten Zeile erhalten wir die spezifische Methode, die nur eine erfolgreiche WinRT-Aufgabe übernimmt. Anschließend definieren wir eine Funktion, die wir mehrmals verwenden, um ein Ergebnis des entsprechenden Typs aus einer asynchronen WinRT-Task zu extrahieren. Nach der Deklaration dieser Funktion laden wir zwei notwendige Typen aus den WinRT-Metadaten . Der Rest des Skripts ist so ziemlich nur eine PowerShell-Übersetzung des C # -Codes, den Sie in Ihrer Antwort geschrieben haben. Es verwendet die Klasse Radio WinRT, um das Bluetooth-Funkgerät zu finden und zu konfigurieren.

15
Ben N

Nachdem ich aufgegeben hatte, nach vorgefertigten Lösungen zu suchen, stellte ich fest, dass die Universal Windows Platform-Apps Zugriff auf die Radio Control API haben.

Daher habe ich eine Beispiel-Funksteuerungs-App mit einer befehlszeilengesteuerten App zusammengeführt. Das Ergebnis ist hier: https://github.com/peci1/RadioControl . Es ist im Windows Store veröffentlicht .

Im Allgemeinen ist es nicht möglich, die App nur im Hintergrund laufen zu lassen. Sie müssen daher zuerst die GUI starten und können sie dann wie folgt über die Befehlszeile aufrufen

radiocontrol.exe 0 on
radiocontrol.exe Bluetooth off

Die Kernfunktionen, die diese App benötigt, sind:

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

Dann müssen Sie auch die Radios-Funktion zum App-Manifest hinzufügen:

<DeviceCapability Name="radios" />

Um die Steuerung über die Befehlszeile zu ermöglichen, müssen Sie die Methode protected override async void OnActivated(IActivatedEventArgs args) in App.xaml.cs überschreiben und die Verarbeitung in einer Verzweigung wie der folgenden ausführen:

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

Dieses Autohotkey-Skript scheint den Trick zu tun. Die Sleep stört mich dort, aber es scheint, dass das Fenster aktiv wird, bevor es zum Empfang meiner Tastatureingaben bereit ist.

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

Crossposting an https://stackoverflow.com/q/48700268/308851 , um herauszufinden, durch was dieser Sleep 300 ersetzt werden könnte.

2
chx

Hier ist eine Teillösung: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\%'" call disable lässt den Bluetooth-Ein/Aus-Schalter auf jeden Fall verschwinden und der Geräte-Manager meldet This device is disabled. (Code 22). Ob das ausreicht, um das Radio auszuschalten, weiß ich nicht.

Ich kann keine Dokumentation darüber finden, welche Argumente call akzeptiert. Ich denke, hier sollte es eine Art rfkill geben.

1
chx

Powershell verfügt über Cmdlets, mit denen Sie genau das tun können, wonach Sie suchen:

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

Verwenden Sie Get-Device, um eine Liste der Geräte abzurufen. Sie können das Where-Objekt weiterleiten, um Ihr Gerät auszuwählen, und dann an Disable-Device oder Enable-Device weiterleiten.

Detaillierte Anleitung...

Laden Sie die Datei herunter und entpacken Sie sie.

Starte eine PowerShell als Admin.

Ändern Sie ggf. die Ausführungsrichtlinie:

Set-ExecutionPolicy Unrestricted

Importieren Sie das Modul:

Import-Module .\DeviceManagement.psd1

Wenn Sie die Liste der Geräte eingrenzen müssen, können Sie einen ähnlichen Vergleich durchführen:

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

Wenn Sie den genauen Namen kennen, können Sie einen -eq (gleich) -Vergleich verwenden:

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

Hände an der Hose abwischen.

0
apocalysque

Sie können DevManView verwenden, um ein Gerät über die Befehlszeile mit folgender Syntax zu aktivieren/deaktivieren:

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

Es erlaubt auch die Verwendung von Platzhaltern mit dem Argument /use_wildcard.

0
rahuldottech

Ich habe ein Batch-Skript erstellt, das einen Registrierungsschlüsselwert überprüft, der nur vorhanden wäre, wenn Ihr Bluetooth-Radio aktiviert wäre. Anschließend ruft es das oben genannte Powershell-Skript von Ben N mit dem richtigen Parameter auf, um den aktuellen Status zu ändern. Verwandelt es in eine Umschaltverknüpfung, anstatt es separat ein- und ausschalten zu müssen.

@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