CreateProcessAsUser与ShellExecute

时间:2008-08-28 23:00:05

标签: winapi windows-nt

我需要ShellExecute作为另一个用户的东西,目前我开始使用调用CreateProcessAsUser的{​​{1}}辅助进程,但这似乎太糟糕了(错误的父进程等) 。)有更好的方法吗?

@PabloG:ImpersonateLoggedOnUser不起作用:

HANDLE hTok;
VERIFY(LogonUser("otheruser",0,"password",LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hTok));
VERIFY(ImpersonateLoggedOnUser(hTok));
ShellExecute(0,0,"calc.exe",0,0,SW_SHOW);
RevertToSelf();
CloseHandle(hTok);

将以登录用户身份开始计算,而非“其他用户”

@ 1800信息:ShellExecute / CreateProcessCreateProcessAsUser不同,在Vista上使用UAC,ShellExecute在您无法控制什么时无效用户正在执行的程序(CreateProcess如果给它一个带有标记为requireAdmin的清单的exe文件,则会返回错误)

@Brian R. Bondy:我已经知道这个信息(并且不要误解我的好东西),但这不是主题(恕我直言)我要求CreateProcess,而不是开始作为另一个用户进行处理,我已经知道如何做到这一点。

4 个答案:

答案 0 :(得分:9)

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

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

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

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

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

    你需要一个这样的调用序列: LogonUser,ExpandEnvironmentStringsForUser,GetLogonSID,LoadUserProfile,CreateEnvironmentBlock,CreateProcessAsUser。

    可以通过任何搜索引擎或Google code search

    找到此示例代码

    关于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: 这也可以这样做,但它要求您已经在运行升级过程。作为本地系统帐户运行的服务确实以提升的方式运行。我也可以通过我想要启动的authenticode签名进程来使它工作。您要启动的进程还必须具有与其关联的清单文件,其中requestedExecutionLevel level =“requireAdministrator”

    其他说明:

    • 您可以通过SetTokenInformation和TokenSessionId
    • 设置令牌的会话
    • 您无法更改已在运行的进程的会话ID。
    • 如果Vista不在等式中,整个过程将变得非常简单。

答案 1 :(得分:1)

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

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

答案 2 :(得分: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

抱歉,不能用“()”

超链接网址

答案 3 :(得分:0)

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

您也可以使用SHCreateProcessAsUserW。