c++ - 尝试显示屏幕保护程序的配置窗口时出现问题(来自以高强制完整性级别运行的 GUI 应用程序)

标签 c++ c windows winapi windows-shell

我有一个旧项目,它带有自己的屏幕保护程序。该项目的 GUI 应用程序有一个“配置屏幕保护程序”选项,该选项应该打开我的屏幕保护程序配置窗口(通常可以从控制面板 -> 显示 -> 个性化 -> 屏幕保护程序 -> 设置获得该窗口。)

要显示配置窗口,需要调用/c参数为described here的屏保进程。 。屏幕保护程序本身放置在系统目录中,即 "C:\Windows\System32"

因此,为了从我的(32 位)GUI 应用程序中模拟这一点,我执行以下操作:

//Error checks are omitted for brevity
BOOL bResult = FALSE;

TCHAR buffSysFldr[MAX_PATH];
buffSysFldr[0] = 0;
::GetSystemDirectory(buffSysFldr, SIZEOF(buffSysFldr));

//Make the path, which basically becomes:
//  "C:\Windows\System32\mysvr.scr" /c
TCHAR buff[MAX_PATH];
buff[0] = 0;
::StringCbPrintf(buff, sizeof(buff), L"\"%s\\mysvr.scr\" /c", buffSysFldr);

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
ZeroMemory(&si,sizeof(si));
ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(si);

PVOID OldValue;
Wow64DisableWow64FsRedirection(&OldValue);

//And run it
if(CreateProcess(NULL, buff, NULL, NULL, FALSE, 
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, 
    NULL, NULL, &si, &pi))
{
    //Success
    bResult = TRUE;
}

Wow64RevertWow64FsRedirection(OldValue);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

当我将其部署到 Windows 7 计算机时,上面的代码返回 bResult = TRUE,但我的屏幕保护程序的配置窗口从未显示。

我在32位和64位Windows 7上都尝试过,认为Wow64重定向与此有关,但它仍然没有改变结果。

知道为什么这不起作用吗?

PS。当我将该命令复制并粘贴到命令提示符中时,它运行得很好并显示我的配置窗口,没有问题:

enter image description here

编辑:经过进一步审查,发现该问题似乎与我的 GUI 应用程序以 High Mandatory Integrity Level 运行这一事实有关。 ,或S-1-16-12288 ,这似乎是屏幕保护程序的配置窗口未显示的原因。如果我以其常规的中等完整性级别或 S-1-16-8192 运行 GUI 应用程序,配置窗口将显示“正常”。

否则,我可以看到我的屏幕保护程序的 RegisterDialogClasses方法被调用 OK,但是当我从它返回 TRUE 时,ScreenSaverConfigureDialog从未被调用过。

由于引入完整性级别是为了防止较低级别的进程向较高级别的进程发送消息,显然屏幕保护程序配置机制尝试向我的 GUI 应用程序发送一些消息(出于任何未记录的原因)并失败,然后默默地失败,如下所示嗯...

所以这是最新的。我将感谢任何知道如何解决这个问题的人提供的任何意见(除了降低我的 GUI 应用程序的完整性级别,我显然不想这样做。)

最佳答案

该死的微软documentation (抱歉,我今天浪费了一整天的时间来修复它。)

对于其他遇到这种情况的人来说——事实证明我们需要这样调用它:

"C:\Windows\System32\mysvr.scr" /c:N

其中 N 是父窗口的窗口句柄,以整数表示。通过检查控制面板显示的配置窗口的命令行找到了它(是否使用 Process Explorer 。)

就我而言,由于我的 GUI 进程以更高的完整性级别运行,因此执行以下操作就足够了:

HWND hWndToUse = ::GetDesktopWindow();
::StringCbPrintf(buff, sizeof(buff), L"\"%s\\mysvr.scr\" /c:%d", buffSysFldr, (int)hWndToUse);

就是这样!

关于c++ - 尝试显示屏幕保护程序的配置窗口时出现问题(来自以高强制完整性级别运行的 GUI 应用程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30430394/

相关文章:

c++ - 侵入式或非侵入式

windows - 基于表的异常处理与 32 位 Windows SEH 相比有何优势?

python - 如何使用 python 禁用 Windows 防火墙

windows - Microsoft Stack 是否始终与 16 字节对齐?

c++ - 是否有 OpenCL std::queue 等价物

c++ - 在 C++03 和 C++14 的代码中进行简单随机改组的最佳做法是什么?

java - Java中OpenCV椭圆检测的问题

c - 如何将完整的字符串写入文件?

c - C中的"identifier not found"

c - 使用 C 暂停执行二进制文件?