CreateProcessAsUser与ShellExecute
我需要以另一个用户的身份执行ShellExecute的操作,目前,我使用CreateProcessAsUser启动了一个调用ShellExecute的帮助程序,但这似乎太过分了(错误的父进程等等)。这?
@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);
只会以登录用户身份而不是" otheruser"身份启动calc
@ 1800信息:CreateProcess
/CreateProcessAsUser
与ShellExecute
不同,在Vista上使用UAC时,如果我们无法控制用户正在执行的程序,则CreateProcess
是没有用的(CreateProcess
将返回如果我们给它一个带有清单文件的exe文件,并且带有标记为requireAdmin的文件,则会出现错误)
@Brian R. Bondy:我已经知道了这个信息(不要误会我,这是很好的东西),但是这不是主题(恕我直言),我要求的是ShellExecuteAsUser,而不是有关以另一个用户身份启动进程的信息,我已经知道该怎么做。
解决方案
回答
我们可以在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
我们为什么不只创建要运行的进程的CreateProcessAsUser?
回答
我们也许也可以使用SHCreateProcessAsUserW。
- 如果我们不需要使用GUI运行该过程并且不需要提升
- 如果我们要运行的用户已经登录到会话中
- 如果我们需要使用GUI运行该过程,则用户可能会或者可能不会登录
- 如果我们需要使用海拔高度运行流程
该解决方案实际上取决于需求,并且可能非常复杂(完全感谢Windows Vista)。这可能超出了需求,但这其他通过搜索找到此页面的人。
关于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签名过程来使其正常工作。我们要启动的进程还必须具有一个清单文件,该清单文件与所请求的ExecutionLevel level =" requireAdministrator"关联。
- 我们可以通过SetTokenInformation和TokenSessionId设置令牌的会话
- 我们无法更改已经运行的进程的会话ID。
- 如果Vista不在考虑范围之内,那么整个过程将大大简化。
回答
其他说明:
如果我们需要ShellExecute语义,则可以提供以下内容:
段落数量不匹配