我创建了一个 PowerShell 脚本,使用
Windows.Devices.Radios
命名空间和 WinRT API 以编程方式启用或禁用 Windows 系统上的 WiFi 或蓝牙无线电。该脚本处理 WinRT API 的异步特性,并无缝切换无线电状态。
下面是启用/禁用 WiFi 或蓝牙无线电的实现。
此 PowerShell 脚本通过 WinRT API 使用
Windows.Devices.Radios
命名空间在 Windows 上启用或禁用 WiFi 或蓝牙。以下是该脚本及其工作原理的详细说明。
# script to enable/disable WiFi or bluetooth in Windows
# [email protected]
cls
Remove-Variable * -ea 0
$ErrorActionPreference = 'stop'
$newStatus = 'On' # On/Off
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$methods = [System.WindowsRuntimeSystemExtensions].GetMethods()
foreach($m in $methods) {
if ($m.Name -ne 'AsTask') {continue}
if ($m.GetParameters().Count -ne 1) {continue}
if ($m.GetParameters()[0].ParameterType.Name -ne 'IAsyncOperation`1') {continue}
$asTaskGeneric = $m
break
}
function await($task, $type) {
$asTask = $asTaskGeneric.MakeGenericMethod($type)
$netTask = $asTask.Invoke($null, $task)
$null = $netTask.Wait(-1)
$netTask.Result
}
$radio = [Windows.Devices.Radios.Radio]
$rList = [System.Collections.Generic.IReadOnlyList[Windows.Devices.Radios.Radio]]
$status = [Windows.Devices.Radios.RadioAccessStatus]
$null = [Windows.Devices.Radios.Radio,Windows.System.Devices,ContentType=WindowsRuntime]
$null = Await -task $radio::RequestAccessAsync() -type $status
$radios = Await -task $radio::GetRadiosAsync() -type $rList
$wifi = $radios | where {$_.Kind -eq 'WiFi'}
$null = Await -task $wifi.SetStateAsync($newStatus) -type $status
# $bt = $radios | where {$_.Kind -eq 'Bluetooth'}
# $null = Await -task $bt.SetStateAsync($newStatus) -type $status
设置所需状态:
$newStatus
变量设置为'On'
或'Off'
以指示是否应启用或禁用无线电(WiFi/蓝牙)。加载所需组件:
System.Runtime.WindowsRuntime
程序集,这是访问 WinRT API 所必需的。找到
AsTask
方法:
AsTask
方法将异步操作(WinRT 中的IAsyncOperation<T>
)转换为 .NET Task
对象。该脚本使用反射动态识别 AsTask
的正确重载。使用
Await
处理异步任务:
await
函数:
AsTask
方法将 WinRT 异步操作转换为 .NET Task
。.Wait()
等待任务完成。请求无线电访问:
RequestAccessAsync
来请求管理无线电的权限。检索和管理无线电:
GetRadiosAsync
方法检索系统上可用的无线电(WiFi、蓝牙等)列表。Kind
属性过滤此列表,以识别所需的无线电(WiFi
或 Bluetooth
)。SetStateAsync
或'On'
)调用'Off'
方法来切换无线电。无线网络:
$wifi = $radios | where {$_.Kind -eq 'WiFi'}
$null = Await -task $wifi.SetStateAsync($newStatus) -type $status
蓝牙:(取消注释以下行以管理蓝牙)
$bt = $radios | where {$_.Kind -eq 'Bluetooth'}
$null = Await -task $bt.SetStateAsync($newStatus) -type $status
await
函数弥合了WinRT的异步操作和PowerShell的同步执行模型之间的差距。这就是为什么这很重要:
WinRT API 在设计上是异步的:
RequestAccessAsync
和 GetRadiosAsync
这样的调用会返回 IAsyncOperation<T>
对象,无法在 PowerShell 中直接等待。AsTask
方法将它们转换为.NET Task
对象,从而实现同步处理。自定义
await
实施:
await
函数使用标识的AsTask
方法来处理异步操作。它确保任务在继续之前完成,为脚本的其余部分提供简单的同步体验。此脚本是 PowerShell 如何与现代 WinRT API 交互以实现高级 Windows 功能(例如以编程方式控制无线电)的绝佳示例。