winapi - CreateProcessAsUser 与 ShellExecute

标签 winapi windows-nt

我需要 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/CreateProcessAsUserShellExecute 不一样,在 Vista 上使用 UAC,CreateProcess当您无法控制用户正在执行的程序时,它是无用的(如果您给它一个带有 list 标记为 requireAdmin 的 exe 文件,CreateProcess 将返回错误)

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

最佳答案

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

  • 如果您不需要使用 GUI 运行该过程并且您不需要提升
  • 如果您要运行的用户已经登录到 session
  • 如果您需要使用 GUI 运行进程,并且用户可能已登录,也可能未登录
  • 如果您需要以海拔
  • 运行该进程

    关于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"

    其他注意事项:
  • 您可以通过 SetTokenInformation 和 TokenSessionId
  • 设置 token 的 session
  • 您不能更改已运行进程的 session ID。
  • 如果 Vista 不在等式中,整个过程将变得更加简单。
  • 关于winapi - CreateProcessAsUser 与 ShellExecute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33594/

    相关文章:

    c++:用随机字节填充缓冲区的最快方法

    c++ - 如何在 Windows 上记录击键 [C++]

    node.js - 错误! Windows_NT 10.0.10586

    java - 在 NT 机器上运行 J6SE 应用程序

    debugging - 如何解释WinDbg中显示的异常代码?

    c++ - 枚举 "real"窗口和子窗口

    c# - 如何使用 C# 获取 Windows 资源管理器中当前打开的所有文件夹的完整路径?

    c++ - WinAPI:在 WM_PAINT 中省略 BeginPaint 和 EndPaint 会导致 100% CPU 使用率