使用 WinRT API 启用/禁用 WiFi 或蓝牙的 PowerShell 脚本

问题描述 投票:0回答:1

我创建了一个 PowerShell 脚本,使用

Windows.Devices.Radios
命名空间和 WinRT API 以编程方式启用或禁用 Windows 系统上的 WiFi 或蓝牙无线电。该脚本处理 WinRT API 的异步特性,并无缝切换无线电状态。

下面是启用/禁用 WiFi 或蓝牙无线电的实现。

windows powershell bluetooth wifi
1个回答
0
投票

此 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

代码逻辑解释

  1. 设置所需状态:

    • $newStatus
      变量设置为
      'On'
      'Off'
      以指示是否应启用或禁用无线电(WiFi/蓝牙)。
  2. 加载所需组件:

    • 该脚本加载
      System.Runtime.WindowsRuntime
      程序集,这是访问 WinRT API 所必需的。
  3. 找到

    AsTask
    方法:

    • AsTask
      方法将异步操作(WinRT 中的
      IAsyncOperation<T>
      )转换为 .NET
      Task
      对象。该脚本使用反射动态识别
      AsTask
      的正确重载。
  4. 使用

    Await
    处理异步任务:

    • 由于 WinRT API 返回异步操作,因此该脚本定义了一个
      await
      函数:
      • 使用
        AsTask
        方法将 WinRT 异步操作转换为 .NET
        Task
      • 使用
        .Wait()
        等待任务完成。
      • 检索任务结果,启用 PowerShell 中异步操作的同步处理。
  5. 请求无线电访问:

    • 脚本首先调用
      RequestAccessAsync
      来请求管理无线电的权限。
  6. 检索和管理无线电:

    • GetRadiosAsync
      方法检索系统上可用的无线电(WiFi、蓝牙等)列表。
    • 脚本根据
      Kind
      属性过滤此列表,以识别所需的无线电(
      WiFi
      Bluetooth
      )。
    • 使用所需状态(
      SetStateAsync
      'On'
      )调用
      'Off'
      方法来切换无线电。

启用 WiFi 和蓝牙

  • 无线网络:

    $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的同步执行模型之间的差距。这就是为什么这很重要:

  1. WinRT API 在设计上是异步的:

    • RequestAccessAsync
      GetRadiosAsync
      这样的调用会返回
      IAsyncOperation<T>
      对象,无法在 PowerShell 中直接等待。
    • AsTask
      方法将它们转换为.NET
      Task
      对象,从而实现同步处理。
  2. 自定义

    await
    实施:

    • await
      函数使用标识的
      AsTask
      方法来处理异步操作。它确保任务在继续之前完成,为脚本的其余部分提供简单的同步体验。

此脚本是 PowerShell 如何与现代 WinRT API 交互以实现高级 Windows 功能(例如以编程方式控制无线电)的绝佳示例。

© www.soinside.com 2019 - 2024. All rights reserved.