关于winapi:CreateProcessAsUser与ShellExecute

关于winapi:CreateProcessAsUser与ShellExecute

CreateProcessAsUser vs ShellExecute

我需要以其他用户身份ShellExecute的东西,当前我用CreateProcessAsUser启动了一个调用ShellExecute的帮助程序,但是这似乎太多了(错误的父进程等)。有没有更好的方法?做到这一点的方法?

@PabloG:ImpersonateLoggedOnUser不起作用:

1
2
3
4
5
6
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);

将仅以登录用户而不是" otheruser"的身份启动calc

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

@Brian R. Bondy:我已经知道了此信息(不要误会,它的好东西),但是我要的是ShellExecuteAsUser,而不是关于启动流程的话题(IMHO),另一个用户,我已经知道该怎么做。


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

  • 如果您不需要使用GUI运行该过程并且不需要提升
  • 如果您要以其身份运行的用户已经登录到会话中
  • 如果您需要使用GUI运行该过程,则用户可能会或可能不会登录
  • 如果您需要使用海拔高度运行流程
  • 关于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:
    也可以完成此操作,但是它要求您已经在运行提升的流程。以本地系统帐户运行的服务确实以提升的身份运行。我还只能通过让我想启动的Authenticode签名过程来使其工作。您要启动的进程还必须具有与清单文件关联的清单文件,该清单文件与requestedExecutionLevel level =" requireAdministrator"

    其他说明:

    • 您可以通过SetTokenInformation和TokenSessionId设置令牌的会话
    • 您无法更改已经运行的进程的会话ID。
    • 如果Vista不在考虑范围之内,那么整个过程将大大简化。

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

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


    为什么不只创建CreateProcessAsUser指定要运行的进程?

    您也许还可以使用SHCreateProcessAsUserW。


    您可以在ImpersonateLoggedOnUser / RevertToSelf

    之间packageShellExecute。

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

    对不起,无法使用"()"超链接URL。


    推荐阅读