Это сложно из-за необходимости взаимодействия с 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
. Этот конкретный метод имеет множество различных наборов параметров, которые, кажется, приводят к снижению разрешения перегрузки PowerShell, поэтому в следующей строке мы получим конкретный метод, который выполняет только результативную задачу WinRT. Затем мы определяем функцию, которую будем использовать несколько раз, чтобы извлечь результат соответствующего типа из асинхронной задачи WinRT. После объявления этой функции мы загружаем два необходимых типа из метаданных WinRT, Остальная часть сценария в значительной степени является просто переводом PowerShell кода C #, который вы написали в своем ответе; он использует Radio
класс WinRT для поиска и настройки радиомодуля Bluetooth.