【问题标题】:Programmatically turn airplane mode on or off Windows以编程方式打开或关闭飞行模式 Windows
【发布时间】:2015-06-13 02:45:07
【问题描述】:

我正在编写一个需要在 Windows 上打开或关闭飞行模式的应用程序。我见过this question,但答案只能获得状态,或者说你不能为 Metro 应用程序做这样的事情。我不制作现代/地铁应用程序,所以我不需要担心应用程序沙盒。

是否有打开/关闭飞行模式的api,我应该如何使用它?

编辑:在我的用例中,我知道我可以控制它,并且用户对此表示满意。

另外,我发现this msdn question 摘录如下:

Windows 8(build 8250),我可以在 Metro Style Network Setting UI 中打开/关闭飞行模式。

如何以编程方式执行此操作?

  1. Microsoft 为无线单选按钮定义了 HID 使用代码(使用:0xC6)。

    问题:无线单选按钮是否有一些虚拟键码?如果是这样,Application 可以通过 Keybd_event 发送这个 keycode。

  2. WLANAPI.dll 导出 API WlanStoreRadioStateOnEnteringAirPlaneMode ,但没​​有该 API 的任何文档。

    问题:您能提供详细信息吗?是用来控制飞行模式的吗,这个API怎么调用?

显然(给出答案的概要),可以使用MobileBroadbandRadioState 枚举检查飞行模式的状态。

HID 路由可能是docs。显然这是一个是否可以将代码 0xc6 发送到 kbd_event 的问题。

EDIT2:显然有一个名为Network Flyout 的窗口,我正在考虑枚举孩子们以找到开关,但我没有取得多大成功。我将不得不使用更多的 Spy++ 来找出答案。

【问题讨论】:

  • 我不知道是否有可访问的 API,但您是否考虑过微软和大多数计算机所有者都不希望您的软件永远 出现扰乱飞行模式做?飞行模式关乎每台计算机数十人的人身安全,如果我将计算机置于飞行模式,那么我该死的不希望你的软件将其退出。
  • 嗯,有 api 调用来连接和断开网络,所以我看不出有什么区别。
  • 用户将设备置于飞行模式时会覆盖所有这些。
  • @ironmark 20 - 找个好律师 - 感觉你可能需要一个
  • @JohnBollinger:这太荒谬了。如果是为了安全,你可以打赌工作人员会检查每一个电子设备,以确保其无线电已关闭。或者设备根本不允许进入机舱。

标签: windows winapi


【解决方案1】:

我通过逆向工程发现了以下所有内容。

Windows 内部用于获取/设置飞行模式的内部 API 使用对“RMsvc”服务(位于“RMApi.dll”中)的 COM 调用。该服务正在导出一个工厂和接口,其中包含获取/设置飞行模式的功能:

#include <Windows.h>
#include <assert.h>
#include <stdio.h>

static GUID const CLSID_RadioManagementAPI = { 0x581333f6, 0x28db, 0x41be, { 0xbc, 0x7a, 0xff, 0x20, 0x1f, 0x12, 0xf3, 0xf6 } };
static GUID const CID_IRadioManager        = { 0xdb3afbfb, 0x08e6, 0x46c6, { 0xaa, 0x70, 0xbf, 0x9a, 0x34, 0xc3, 0x0a, 0xb7 } };

typedef IUnknown IUIRadioInstanceCollection; /* Didn't bother rev-engineering this one... */
typedef DWORD _RADIO_CHANGE_REASON;

typedef struct IRadioManagerVtbl IRadioManagerVtbl;
typedef struct IRadioManager {
    IRadioManagerVtbl *lpVtbl;
} IRadioManager;
struct IRadioManagerVtbl {
    /* IUnknown */
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(IRadioManager *This, GUID const *riid, LPVOID *ppvObj);
    ULONG (STDMETHODCALLTYPE *AddRef)(IRadioManager *This);
    ULONG (STDMETHODCALLTYPE *Release)(IRadioManager *This);
    /* IRadioManager (aka. `CUIRadioManager') */
    HRESULT (STDMETHODCALLTYPE *IsRMSupported)(IRadioManager *This, DWORD *pdwState);
    HRESULT (STDMETHODCALLTYPE *GetUIRadioInstances)(IRadioManager *This, IUIRadioInstanceCollection **param_1);
    HRESULT (STDMETHODCALLTYPE *GetSystemRadioState)(IRadioManager *This, int *pbEnabled, int *param_2, _RADIO_CHANGE_REASON *param_3);
    HRESULT (STDMETHODCALLTYPE *SetSystemRadioState)(IRadioManager *This, int bEnabled);
    HRESULT (STDMETHODCALLTYPE *Refresh)(IRadioManager *This);
    HRESULT (STDMETHODCALLTYPE *OnHardwareSliderChange)(IRadioManager *This, int param_1, int param_2);
};

int main() {
    HRESULT hr;
    IRadioManager *irm;
    hr = CoInitialize(NULL);
    assert(!FAILED(hr));
    irm = NULL;
    hr = CoCreateInstance(&CLSID_RadioManagementAPI, NULL, 4,
                          &CID_IRadioManager, (void **)&irm);
    assert(!FAILED(hr) && irm);
    int bOldMode, b;
    _RADIO_CHANGE_REASON c;
    hr = irm->lpVtbl->GetSystemRadioState(irm, &bOldMode, &b, &c);
    assert(!FAILED(hr));
    printf("Old flight-mode state was: %s\n", bOldMode == 0 ? "on" : "off");
    /* Set flight mode to the opposite state. */
    hr = irm->lpVtbl->SetSystemRadioState(irm, bOldMode == 0 ? 1 : 0);
    assert(!FAILED(hr));
    irm->lpVtbl->Release(irm);
    CoUninitialize();
    return 0;
}

【讨论】:

  • 编译此代码时,我收到以下错误:- 错误:';'预期(得到“IUIRadioInstanceCollection”)
  • @maverick 我猜你的 没有定义 IUnknown 出于某种原因(错误可能是指“typedef IUnknown IUIRadioInstanceCollection;”,但下次请提供更多细节)。去看看你的系统头文件有什么问题,因为我可以将它复制+粘贴到一个新文件中并执行gcc -o out.exe file.c -lOle32,它工作得很好。哦:如果这不起作用(它应该这样做,并且它不这样做意味着你的构建设置有问题),你可以用 typedef void *IUIRadioInstanceCollection; 替换该行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多