尝试为我的屏幕保护程序显示配置 window 的问题(来自 GUI 应用 运行 高强制完整性级别)

Issues trying to display a configuration window for my screensaver (from a GUI app running with high mandatory integrity level)

我有一个带有自己的屏幕保护程序的旧项目。该项目的 GUI 应用程序有一个 "Configure screensaver" 选项,它应该调出我的屏幕保护程序配置 window(您通常会从控制面板 -> 显示 -> 个性化 -> 屏幕保护程序 -> 设置中获得。 )

要显示配置 window,需要使用 /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 机器时,上面的代码 returns bResult = TRUE 但是我的屏幕保护程序的配置 window 从未显示。

我在32位和64位上都试过了Windows7 以为是Wow64重定向有关系,结果还是没变

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

PS。当我将该命令复制并粘贴到命令提示符时,它 运行 很好并显示我的配置 window w/o 一个问题:

编辑: 经过进一步审查,发现问题似乎与我的 GUI 应用程序 运行s 与 High Mandatory Integrity Level, or S-1-16-12288 有关,这似乎是屏幕保护程序的配置 window 没有显示的原因。如果我 运行 我的 GUI 应用程序具有常规的中等完整性级别,或者 S-1-16-8192,配置 window 显示正常。

否则,我可以看到我的屏幕保护程序的 RegisterDialogClasses method is called OK, but then when I return TRUE from it, ScreenSaverConfigureDialog 从未被调用。

由于引入了完整性级别以防止级别较低的进程向级别较高的进程发送消息,显然屏幕保护程序配置机制试图将一些消息发送到我的 GUI 应用程序(出于任何未记录的原因)并失败,然后静默也失败了...

这是最新的。无论谁知道如何解决这个问题(除了降低我的 GUI 应用程序的完整性级别,我显然不想这样做),我都会很感激。)

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

对于遇到此问题的任何其他人 - 事实证明需要这样称呼它:

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

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

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

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

就是这样!