为什么从服务子进程调用时 CreateProcessAsUser 失败并显示 "Access denied"

Why CreateProcessAsUser fails with "Access denied" when called from service child process

我正在尝试 运行 使用 CreateProcessAsUser 函数从我的服务中以其他用户的身份进行处理。代码示例可在此处 找到。 OS - Windows 10

我的代码工作正常,当我 运行 它在主服务进程中时。但我需要 运行 来自子服务进程的相同代码。在这种情况下,CreateProcessAsUser returns 0 和 GetLastError = 5(拒绝访问)。

子服务进程由下次调用创建

CreateProcess(NULL, "d:\child.exe", NULL, NULL, FALSE, 0u, NULL, NULL, &si.StartupInfo, &pi)

我的代码在 "child.exe" 二进制文件中运行,应该再创建一个进程,以这种方式启动 "d:\test.exe" 二进制文件

CreateProcessAsUser(hUserTokenDup,
        NULL,
        "d:\test.exe",
        NULL,
        NULL,
        FALSE,
        CREATE_NEW_CONSOLE | /*CREATE_BREAKAWAY_FROM_JOB |*/ NORMAL_PRIORITY_CLASS,
        NULL,
        NULL,
        &si,
        &pi);

为了测试,我将启动 "test.exe" 的代码移动到 "child.exe" 启动的相同位置(服务主进程)并且 "test.exe" 启动正常。为了进行测试,我用相同的参数(用户令牌除外)替换了 CreateProcess 上的 CreateProcessAsUser 并且 test.exe 也可以正常启动。

但我需要从服务子进程(从 "child.exe")启动 "test.exe" 并通过 CreateProcessAsUser 启动它。我尝试了很多来自互联网的解决方案(添加 CREATE_BREAKAWAY_FROM_JOB、使用 DuplicateTokenEx、使用 linkedToken、启用所有可能的权限等等)但没有解决方案有帮助。我不希望服务进程和子进程之间有任何区别。但是看起来有些不同,我找不到它是什么。

任何人都可以建议,主服务器进程和它的子进程有什么区别?

我的同事找到了解决方案。

我在这里发布:

在创建服务子进程之前,将标志 JOB_OBJECT_LIMIT_BREAKAWAY_OK|JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 传递给服务器进程中的 SetInformationJobObject 函数后,服务子进程可以启动子进程。之后调用

WTSGetActiveConsoleSessionId(..

WTSQueryUserToken(...

CreateProcessAsUser(...CREATE_BREAKAWAY_FROM_JOB

在不创建重复句柄的情况下处理好事件