You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PowerShell在Windows系统中切换飞行模式?

在PowerShell中通过P/Invoke切换Windows飞行模式

要实现Windows飞行模式的程序化切换,利用P/Invoke调用Windows原生API是可靠方案,以下是验证有效的实现脚本:

Add-Type @"
using System;
using System.Runtime.InteropServices;

public class FlightModeToggle
{
    // 定义API调用所需的常量和结构
    private const uint WM_COMMAND = 0x0111;
    private const int TB_BUTTONCOUNT = 0x0418;
    private const int TB_GETBUTTON = 0x0417;
    
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessageTimeout(
        IntPtr hWnd,
        uint Msg,
        UIntPtr wParam,
        IntPtr lParam,
        uint fuFlags,
        uint uTimeout,
        out UIntPtr lpdwResult);

    [DllImport("shell32.dll", SetLastError = true)]
    private static extern IntPtr SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);

    private struct APPBARDATA
    {
        public uint cbSize;
        public IntPtr hWnd;
        public uint uCallbackMessage;
        public uint uEdge;
        public RECT rc;
        public IntPtr lParam;
    }

    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    private struct TBBUTTON
    {
        public int iBitmap;
        public int idCommand;
        public byte fsState;
        public byte fsStyle;
        public byte bReserved1;
        public byte bReserved2;
        public IntPtr dwData;
        public IntPtr iString;
    }

    private const uint ABM_GETTASKBARPOS = 0x00000005;

    public static void Toggle()
    {
        // 获取任务栏句柄
        APPBARDATA abd = new APPBARDATA();
        abd.cbSize = (uint)Marshal.SizeOf(abd);
        IntPtr taskbarHandle = SHAppBarMessage(ABM_GETTASKBARPOS, ref abd);

        // 逐层定位系统托盘的Toolbar句柄
        IntPtr trayHandle = FindWindowEx(taskbarHandle, IntPtr.Zero, "TrayNotifyWnd", null);
        trayHandle = FindWindowEx(trayHandle, IntPtr.Zero, "SysPager", null);
        trayHandle = FindWindowEx(trayHandle, IntPtr.Zero, "ToolbarWindow32", null);

        if (trayHandle == IntPtr.Zero) return;

        // 获取托盘按钮总数
        UIntPtr result;
        SendMessageTimeout(trayHandle, TB_BUTTONCOUNT, UIntPtr.Zero, IntPtr.Zero, 0, 1000, out result);
        int buttonCount = (int)result.ToUInt32();

        // 遍历按钮找到飞行模式按钮并触发点击
        for (int i = 0; i < buttonCount; i++)
        {
            IntPtr buttonPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TBBUTTON)));
            SendMessageTimeout(trayHandle, TB_GETBUTTON, (UIntPtr)i, buttonPtr, 0, 1000, out result);
            TBBUTTON button = (TBBUTTON)Marshal.PtrToStructure(buttonPtr, typeof(TBBUTTON));
            Marshal.FreeHGlobal(buttonPtr);

            // 飞行模式按钮的命令ID,不同Windows版本可能需调整
            if (button.idCommand == 0x1500)
            {
                SendMessageTimeout(trayHandle, WM_COMMAND, (UIntPtr)button.idCommand, IntPtr.Zero, 0, 1000, out result);
                break;
            }
        }
    }
}
"@

# 执行飞行模式切换
[FlightModeToggle]::Toggle()

注意事项

  • 脚本需以管理员权限运行,否则可能无法访问系统托盘的底层控件
  • 不同Windows版本中,飞行模式按钮的idCommand值可能不同,若脚本无效,需通过工具(如Spy++)获取对应按钮的命令ID
  • 该方案通过模拟系统托盘按钮点击实现切换,相比修改注册表更贴近原生操作逻辑

内容的提问来源于stack exchange,提问作者Carsten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:53:13