Jest to trudne ze względu na niezbędną współpracę z WinRT, ale jest to możliwe w czystej 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
Aby go użyć, zapisz plik PS1, np bluetooth.ps1
. Jeśli jeszcze tego nie zrobiłeś, postępuj zgodnie z instrukcjami w sekcji Włączanie skryptów wiki tagu PowerShell, aby włączyć wykonywanie skryptów w systemie. Następnie możesz uruchomić go z wiersza polecenia programu PowerShell w następujący sposób:
.\bluetooth.ps1 -BluetoothStatus On
Aby wyłączyć Bluetooth, przekaż Off
zamiast.
Aby uruchomić go z pliku wsadowego:
powershell -command .\bluetooth.ps1 -BluetoothStatus On
Zastrzeżenie: Jeśli usługa wsparcia Bluetooth nie jest uruchomiona, skrypt próbuje ją uruchomić, ponieważ w przeciwnym razie WinRT nie zobaczy radia Bluetooth. Niestety usługi nie można uruchomić, jeśli skrypt nie działa jako administrator. Aby było to niepotrzebne, możesz zmienić typ uruchamiania tej usługi na automatyczny.
Teraz trochę wyjaśnienia. Pierwsze trzy wiersze określają parametry, które przyjmuje skrypt. Zanim zaczniemy na poważnie, upewnimy się, że usługa pomocy technicznej Bluetooth jest uruchomiona i uruchom ją, jeśli nie. Następnie ładujemy System.Runtime.WindowsRuntime
zestaw, abyśmy mogli użyć WindowsRuntimeSystemExtensions.AsTask
metody do konwersji zadań w stylu WinRT (których .NET / PowerShell nie rozumie) na .NET Task
. Ta konkretna metoda ma mnóstwo różnych zestawów parametrów, które wydają się wyzwalać rozdzielczość przeciążenia PowerShell, więc w następnym wierszu otrzymujemy konkretny, który przyjmuje tylko wynikowe zadanie WinRT. Następnie definiujemy funkcję, której użyjemy kilka razy, aby wyodrębnić wynik odpowiedniego typu z asynchronicznego zadania WinRT. Po deklaracji tej funkcji ładujemy dwa niezbędne typy z metadanych WinRT. Pozostała część skryptu to właściwie tylko tłumaczenie PowerShell kodu C # napisanego w odpowiedzi; używa Radio
klasy WinRT do wyszukiwania i konfigurowania radia Bluetooth.