我需要 ShellExecute
作为另一个用户,目前我使用 CreateProcessAsUser
启动一个辅助进程调用 ShellExecute
,但这似乎太过分了(错误的父进程等)。有没有更好的方法来做到这一点?
@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
/CreateProcessAsUser
与 ShellExecute
不一样,在 Vista 上使用 UAC,CreateProcess
当您无法控制用户正在执行的程序时,它是无用的(如果您给它一个带有 list 标记为 requireAdmin 的 exe 文件,CreateProcess
将返回错误)
@Brian R. Bondy:我已经知道这个信息(别误会,它的好东西),但它是题外话(恕我直言)我要求 ShellExecuteAsUser
,而不是作为另一个用户启动进程,我已经知道如何做到这一点。
最佳答案
解决方案实际上取决于您的需求,并且可能非常复杂(完全感谢 Windows Vista)。这可能超出您的需要,但这将有助于通过搜索找到此页面的其他人。
关于1:
在 Windows Vista 中,存在一种称为 session 0 隔离的东西。所有服务都作为 session 0 运行,并且您不应该在 session 0 中有 GUI。第一个登录的用户登录到 session 1。在 Windows 的早期版本(Vista 之前)中,第一个登录的用户也完全运行在 session 0。
您可以在同一 session 中使用不同的用户名运行多个不同的进程。您可以找到关于 session 0 隔离的好文档 here .
由于我们正在处理选项 1),因此您不需要 GUI。因此,您可以在 session 0 中开始您的进程。
你会想要一个像这样的调用序列:
LogonUser、ExpandEnvironmentStringsForUser、GetLogonSID、LoadUserProfile、CreateEnvironmentBlock、CreateProcessAsUser。
可以通过任何搜索引擎或通过 Google code search 找到此示例代码。
关于2:如果您希望运行该流程的用户已经登录,您可以简单地使用:WTSEnumerateSessions 和 WTSQuerySessionInformation 来获取 session ID,然后使用 WTSQueryUserToken 来获取用户 token 。从那里您可以在 CreateProcessAsUser Win32 API 中使用用户 token 。
这是一个很好的方法,因为您甚至不需要以用户身份登录,也不知道用户的用户名/密码。我相信这只能通过服务作为本地系统帐户运行。
您可以通过 WTSGetActiveConsoleSessionId 获取当前 session 。
关于3:
您将按照与 #1 相同的步骤进行操作,但另外您将使用 STARTUPINFO 的 lpDesktop 字段。将此设置为 winsta0\Default。您还需要尝试使用 OpenDesktop Win32 API,如果失败,您可以使用 CreateDesktop。在使用工作站和桌面句柄之前,您应该使用 SE_WINDOW_OBJECT 和 GROUP_SECURITY_INFORMATION | 在每个句柄上使用 SetSecurityInfo。 DACL_SECURITY_INFORMATION。
如果有问题的用户稍后尝试登录,他实际上会看到正在运行的进程。
关于4:
这也可以完成,但它要求您已经在运行提升的进程。作为本地系统帐户运行的服务确实以提升的身份运行。我也只能通过我想要启动的验证码签名过程来让它工作。您要启动的进程还必须具有与其关联的 list 文件,其中 requestedExecutionLevel level="requireAdministrator"
其他注意事项:
关于winapi - CreateProcessAsUser 与 ShellExecute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33594/