c++ - 无法在 Windows 10 下关闭 OSK.exe

标签 c++ winapi mfc win32gui

我使用下面的代码打开osk.exe

HINSTANCE Dlg::ExecuteOSK()
{
    typedef BOOL (WINAPI * LPFN_IsWow64Process)(HANDLE, PBOOL);
    typedef BOOL (WINAPI * LPFN_Wow64DisableWow64FsRedirection)(PVOID *);
    typedef BOOL (WINAPI * LPFN_Wow64RevertWow64FsRedirection)(PVOID);
    LPFN_IsWow64Process fnIsWow64Process = NULL;
    LPFN_Wow64DisableWow64FsRedirection fnWow64DisableWow64FsRedirection = NULL;
    LPFN_Wow64RevertWow64FsRedirection fnWow64RevertWow64FsRedirection = NULL;
    fnIsWow64Process = (LPFN_IsWow64Process) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
    fnWow64DisableWow64FsRedirection = (LPFN_Wow64DisableWow64FsRedirection) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "Wow64DisableWow64FsRedirection");
    fnWow64RevertWow64FsRedirection = (LPFN_Wow64RevertWow64FsRedirection) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "Wow64RevertWow64FsRedirection");
    BOOL bIsWow64 = FALSE;
    PVOID OldValue = NULL;
    HINSTANCE handle;
    if (NULL == fnIsWow64Process || NULL == fnWow64DisableWow64FsRedirection || NULL == fnWow64RevertWow64FsRedirection)
    {
        handle = ::ShellExecute(NULL, "open", "OSK", NULL, NULL, SW_SHOW);
    }
    else
    {
        fnIsWow64Process(GetCurrentProcess(), &bIsWow64);

        if (TRUE == bIsWow64)
        {
            fnWow64DisableWow64FsRedirection(&OldValue);
            handle = ::ShellExecute(NULL, "open", "OSK", NULL, NULL, SW_SHOW);
            fnWow64RevertWow64FsRedirection(OldValue);
        }
        else
        {
            handle = ::ShellExecute(NULL, "open", "OSK", NULL, NULL, SW_SHOW);
        }
    }
    return handle;
}

然后,我想在用户按 Enter 时关闭 osk.exe。

BOOL CALLBACK EnumWindowsProc(
  _In_ HWND   hwnd,
   _In_ LPARAM lParam)
{
    char name[256];
    GetClassName( hwnd, name, sizeof(name) );
    if(strcmp(name,"OSKMainClass") == 0)
        SendMessage(hwnd, WM_CLOSE  , NULL, NULL); //I have tried WM_DESTROY
    return TRUE;
}

BOOL Dlg::PreTranslateMessage(MSG* pMsg) 
{
    if (pMsg->message == WM_KEYDOWN)
    {       
        int nKey = (int)pMsg->wParam;       

        switch(nKey)            
        {
        case VK_RETURN:     
            EnumWindows(EnumWindowsProc, NULL);

        }
    }

    return CBitmapDialog::PreTranslateMessage(pMsg);
}

但是,这部分代码不能用来成功关闭osk.exe。

我 try catch 另一个窗口,它可以成功关闭。

这是 Windows 10 上的问题吗?

最佳答案

如果您想查看 osk.exe 的 list 接下来您可以在这里查看 - uiAccess="true"这是User Interface Privilege Isolation (UIPI) ,还阅读了类似的问题 UIAccess in Manifest Files

因为osk.exeuiAccess="true"在 list 中它有 Mandatory Label\High Mandatory Level在 token 中。但是您的应用程序,如果在未提升的 UAC 下运行,通常会有 Medium Mandatory Level 。结果:

A lower-privilege process cannot:

  • Use SendMessage or PostMessage to application windows running with higher rights. These APIs return success but silently drop the window message.

但是如果你的应用程序得到 High Mandatory Level在代币中 - 您可以关闭 osk.exe通过下一个代码:

if (HWND hwnd = FindWindow(L"OSKMainClass", 0))
{
    PostMessage(hwnd, WM_CLOSE, 0, 0);
}

所以你需要 <requestedExecutionLevel level='requireAdministrator' uiAccess='false'/>在 list 中或以某种方式以提升的方式运行您的应用程序

关于c++ - 无法在 Windows 10 下关闭 OSK.exe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42359657/

相关文章:

c++ - Visual Studio C++ 组合框控件不适用于多字节字符集

c++ - 模板向后兼容 gcc 4.7

c++ - 如何在 C++ 中更改 STL 容器的大小

c++ - QMediaPlayer 和 QVideoWidget 的糟糕表现

c++ - 使用就地 lambda 进行复杂的初始化,尤其是 const

C++:GetPrivateProfileStringA - 随机值?

c++ - OPENFILENAME 打开对话框

visual-studio-2010 - 如何删除类似 Office 的按钮,但保留功能区?

c++ - 读取和写入注册表项。 C++ MFC MBCS。

c++ - 写入时 WaitForMultipleObjects 访问冲突