我正在寻找示例代码:
对于服务调用CreateProcessAsUser()我希望进程在用户的会话中运行,而不是会话0
到目前为止,创建的进程仅像会话0中的服务一样运行
答案 0 :(得分:3)
这是从一些从服务启动控制台应用程序的旧代码中删除的。它在NT4下工作但我还没有用现代版本的Windows进行测试,因此无法保证它能像在NT4上那样工作。
编辑:不,那不会按原样运作。您需要添加找到here的代码来创建桌面,设置SID等。 if (!LogonUser(userId,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hUserToken))
{
return GetLastError();
}
if (!ImpersonateLoggedOnUser(hUserToken))
{
DWORD rc = GetLastError();
CloseHandle(hUserToken);
return rc;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
rc = CreateProcessAsUser(hUserToken, // user token
0, // app name
"foo.exe", // command line
0, // process attributes
0, // thread attributes
FALSE, // don't inherit handles
DETACHED_PROCESS, // flags
0, // environment block
0, // current dir
&si, // startup info
&pi); // process info gets put here
if (!rc)
{
DWORD rc = GetLastError();
RevertToSelf();
CloseHandle(hUserToken);
return rc;
}
RevertToSelf();
CloseHandle(hUserToken);
return 0;
答案 1 :(得分:0)
我知道这是一篇古老的帖子,但我碰巧正在研究这个问题,所以这里有一些适合我的代码。
确定当前登录用户的会话ID
DWORD GetCurrentSessionId ()
{
WTS_SESSION_INFO *pSessionInfo;
DWORD n_sessions = 0;
BOOL ok = WTSEnumerateSessions (WTS_CURRENT_SERVER, 0, 1, &pSessionInfo, &n_sessions);
if (!ok)
return 0;
DWORD SessionId = 0;
for (DWORD i = 0; i < n_sessions; ++i)
{
if (pSessionInfo [i].State == WTSActive)
{
SessionId = pSessionInfo [i].SessionId;
break;
}
}
WTSFreeMemory (pSessionInfo);
return SessionId;
}
以当前登录用户身份启动流程
bool LaunchProcess (const char *process_path)
{
DWORD SessionId = GetCurrentSessioId ();
if (SessionId == 0) // no-one logged in
return false;
HANDLE hToken;
BOOL ok = WTSQueryUserToken (SessionId, &hToken);
if (!ok)
return false;
void *environment = NULL;
ok = CreateEnvironmentBlock (&environment, hToken, TRUE);
if (!ok)
{
CloseHandle (hToken);
return false;
}
STARTUPINFO si = { sizeof (si) } ;
PROCESS_INFORMATION pi = { } ;
si.lpDesktop = "winsta0\\default";
// Do NOT want to inherit handles here
DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT;
ok = CreateProcessAsUser (hToken, process_path, NULL, NULL, NULL, FALSE,
dwCreationFlags, environment, NULL, &si, &pi);
DestroyEnvironmentBlock (environment);
CloseHandle (hToken);
if (!ok)
return false;
CloseHandle (pi.hThread);
CloseHandle (pi.hProcess);
return true;
}