Это сложно из-за необходимости взаимодействия с WinRT, но это возможно в чистом 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
Чтобы использовать его, сохраните его в файл PS1, например, bluetooth.ps1
. Если вы этого еще не сделали, следуйте инструкциям в разделе «Включение сценариев» вики-тега PowerShell, чтобы включить выполнение сценариев в вашей системе. Затем вы можете запустить его из командной строки PowerShell следующим образом:
.\bluetooth.ps1 -BluetoothStatus On
Чтобы выключить Bluetooth, вместо этого передайте Off
.
Чтобы запустить его из командного файла:
powershell -command .\bluetooth.ps1 -BluetoothStatus On
Предупреждение: если служба поддержки Bluetooth не запущена, сценарий пытается запустить ее, потому что в противном случае WinRT не увидит радио Bluetooth. Увы, сервис не может быть запущен, если скрипт не работает от имени администратора. Чтобы сделать это ненужным, вы можете изменить тип запуска этой службы на автоматический.
Теперь для некоторого объяснения. Первые три строки устанавливают параметры, которые принимает скрипт. Прежде чем начать всерьез, мы должны убедиться, что служба поддержки Bluetooth работает, и запустить ее, если нет. Затем мы загружаем System.Runtime.WindowsRuntime
чтобы мы могли использовать WindowsRuntimeSystemExtensions.AsTask
для преобразования задач в стиле WinRT (чего не понимает .NET/PowerShell) в .NET Task
s. Этот конкретный метод имеет множество различных наборов параметров, которые, по-видимому, приводят к снижению разрешения перегрузки PowerShell, поэтому в следующей строке мы получим конкретный метод, который принимает только результативную задачу WinRT. Затем мы определяем функцию, которую будем использовать несколько раз, чтобы извлечь результат соответствующего типа из асинхронной задачи WinRT. После объявления этой функции мы загружаем два необходимых типа из метаданных WinRT. Остальная часть сценария в значительной степени является просто переводом PowerShell кода C #, который вы написали в своем ответе; он использует класс Radio
WinRT для поиска и настройки радио Bluetooth.