在服务的用户会话中创build进程

我正在尝试使一个服务Windows打开的会话中创build一个进程。 我有这个代码:

sessionId =WTSGetActiveConsoleSessionId(); if (WTSQueryUserToken(sessionId,&dummy)) { if (!DuplicateTokenEx(dummy, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenPrimary, &token)) { CloseHandle(dummy); return false; } CloseHandle(dummy); // Create process for user with desktop myfile = fopen("c:\\temp\\test123.txt", "a"); fprintf(myfile, "before create!!!!\n"); fclose(myfile); if (!CreateProcessAsUser(token, NULL,NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { // The "new console" is necessary. Otherwise the process can hang our main process CloseHandle(token); myfile = fopen("c:\\temp\\test123.txt", "a"); fprintf(myfile, " create failed!\n"); fclose(myfile); return false; } CloseHandle(token); } else { myfile = fopen("c:\\temp\\test123.txt", "a"); fprintf(myfile, "Dummy fail\n"); fprintf(myfile, "last error is %d \n", GetLastError()); fclose(myfile); } //int ret = CreateProcess(FILE_EXEC, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); 

如果我使用安装的服务中的最后一个lin(注释)所有工作正常,因为它运行时,服务已安装,所以它发生在用户会话内,但是当我想服务做到这一点失败,sessionId是好的,失败开始于:

  if (WTSQueryUserToken(sessionId,&dummy)) { 

我知道WTSQueryUserToken是一个应该从服务运行的函数,sessionid是1(这是从cmd检查真实数字),假人假设后面持有的用户令牌,但由于某种原因失败….有任何想法吗?

我在我自己的服务中使用类似于您的代码,它工作正常。 有些事情需要考虑到,你所展示的代码没有做到:

  1. 调用WTSQueryUserToken() ,您必须确保您的服务进程已启用SE_TCB_NAME权限。 为此使用AdjustTokenPrivileges()

  2. WTSGetActiveConsoleSessionId()返回的会话ID 可能不是正确的会话,您需要运行您的衍生进程! 它返回连接到本地机器的物理控制台 (屏幕/键盘/鼠标)的会话ID(如果有的话)。 该会话可能正在显示安全的WinLogon桌面,这意味着没有用户实际登录到物理机器,因此在该会话ID上调用WTSQueryUserToken()将失败,并显示ERROR_NO_TOKEN错误。 例如,用户可以通过远程桌面连接登录,在这种情况下,该连接将在与控制台不同的会话中运行。 如果您希望生成的进程在用户已登录的会话中运行,则需要使用WTSEnumerateSessions()来查找处于WTSActive状态的会话。 即使如此, WTSQueryUserToken()可能不会返回一个令牌,这取决于用户的登录方式,所以您需要在每个找到的活动会话中调用WTSQueryUserToken() ,直到找到一个成功给予您的令牌为止。

  3. 当调用DuplicateTokenEx() ,请使用SecurityIdentification而不是SecurityDelegation

  4. 当调用CreateProcessAsUser() ,您可以先调用CreateEnvironmentBlock()以创建适合于该特定用户的环境,然后将该指针传递给CreateProcessAsUser() 否则,产生的进程将使用你的服务的环境。 这一步是可选的,取决于产生的应用程序的特定需求。