4

作为另一个用户,我需要一些东西,目前我用那个调用ShellExecute启动了一个辅助进程,但这似乎太过分了(错误的父进程等)。有没有更好的方法来做到这一点?CreateProcessAsUserShellExecute

@PabloG:ImpersonateLoggedOnUser 不起作用:

处理 hTok;
VERIFY(LogonUser("otheruser",0,"password",LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hTok));
验证(ImpersonateLoggedOnUser(hTok));
ShellExecute(0,0,"calc.exe",0,0,SW_SHOW);
RevertToSelf();
关闭句柄(hTok);

将以登录用户身份启动 calc,而不是“其他用户”

@1800 信息:CreateProcess/CreateProcessAsUserShellExecuteVista 上的 UAC 不同,CreateProcess当您无法控制用户正在执行的程序时,它是无用的(CreateProcess如果您给它一个带有清单标记为的 exe 文件,则会返回错误)要求管理员)

@Brian R. Bondy:我已经知道这个信息(不要误会,它的好东西),但它是题外话(恕我直言)我要求一个ShellExecuteAsUser,而不是作为另一个用户启动进程,我已经知道怎么做。

4

4 回答 4

9

解决方案实际上取决于您的需求,并且可能非常复杂(完全感谢 Windows Vista)。这可能超出您的需要,但这将有助于通过搜索找到此页面的其他人。

  1. 如果您不需要使用 GUI 运行该过程并且您不需要提升
  2. 如果您要运行的用户已经登录到会话
  3. 如果您需要使用 GUI 运行该过程,并且用户可能已登录,也可能未登录
  4. 如果您需要使用海拔运行流程

关于 1: 在 Windows Vista 中存在称为会话 0 隔离的东西。所有服务都作为会话 0 运行,并且您不应该在会话 0 中有 GUI。第一个登录的用户登录到会话 1。在以前版本的 windows(Vista 之前)中,第一个登录的用户也完全运行在会话 0。

您可以在同一会话中使用不同的用户名运行多个不同的进程。您可以在此处找到有关会话 0 隔离的好文档。

由于我们正在处理选项 1),因此您不需要 GUI。因此,您可以在会话 0 中开始您的进程。

您需要一个类似这样的调用序列:LogonUser、ExpandEnvironmentStringsForUser、GetLogonSID、LoadUserProfile、CreateEnvironmentBlock、CreateProcessAsUser。

可以通过任何搜索引擎或通过Google 代码搜索找到此示例代码

关于 2: 如果您希望运行该进程的用户已经登录,您可以简单地使用:WTSEnumerateSessions 和 WTSQuerySessionInformation 来获取会话 ID,然后使用 WTSQueryUserToken 来获取用户令牌。从那里您可以在 CreateProcessAsUser Win32 API 中使用用户令牌。

这是一个很好的方法,因为您甚至不需要以用户身份登录,也不知道用户的用户名/密码。我相信这只能通过服务作为本地系统帐户运行。

您可以通过 WTSGetActiveConsoleSessionId 获取当前会话。

关于 3: 您将遵循与 #1 相同的步骤,但此外您将使用 STARTUPINFO 的 lpDesktop 字段。将此设置为 winsta0\Default。您还需要尝试使用 OpenDesktop Win32 API,如果失败,您可以使用 CreateDesktop。在使用工作站和桌面句柄之前,您应该使用 SE_WINDOW_OBJECT 和 GROUP_SECURITY_INFORMATION | 在每个句柄上使用 SetSecurityInfo。DACL_SECURITY_INFORMATION。

如果有问题的用户稍后尝试登录,他实际上会看到正在运行的进程。

关于 4: 这也可以完成,但它要求您已经在运行提升的进程。作为本地系统帐户运行的服务确实以提升的身份运行。我也只能通过我想要启动的验证码签名过程来让它工作。您要启动的进程还必须具有与其关联的清单文件,其中 requestedExecutionLevel level="requireAdministrator"

其他注意事项:

  • 您可以通过 SetTokenInformation 和 TokenSessionId 设置令牌的会话
  • 您不能更改已运行进程的会话 ID。
  • 如果 Vista 不在等式中,整个过程将变得更加简单。
于 2008-08-30T04:47:10.973 回答
2

如果您需要 ShellExecute 语义,您可以提供以下内容:

C:\windwos\system32\cmd.exe /k" start <your_target_to_be_ShellExecuted>" 你就CreateProcessAsUser完成了。

于 2009-06-18T14:03:58.280 回答
0

您可以在 ImpersonateLoggedOnUser / RevertToSelf 之间包装 ShellExecute

链接:ImpersonateLoggedOnUser: http: //msdn.microsoft.com/en-us/library/aa378612 (VS.85).aspx RevertToSelf:http: //msdn.microsoft.com/en-us/library/aa379317.aspx

抱歉,不能用“()”超链接 URL

于 2008-08-28T23:40:43.680 回答
0

为什么不直接执行 CreateProcessAsUser 指定要运行的进程?

您也可以使用 SHCreateProcessAsUserW。

于 2008-08-29T02:10:42.587 回答