该CreateProcessAsUser函数创建一个新的进程及其主线程。新进程然后执行指定的可执行文件。该CreateProcessAsUser功能类似 的CreateProcess 函数,除了新进程运行在由 hToken 参数表示的用户的安全上下文中。默认情况下,新进程是非交互式的,即它运行在不可见且无法接收用户输入的桌面上。此外,默认情况下,新进程继承调用进程的环境,而不是与指定用户关联的环境。

BOOL CreateProcessAsUser(

HANDLE hToken , // 处理代表登录用户的令牌
LPCTSTR lpApplicationName , // 指向可执行模块名称的指针
LPTSTR lpCommandLine , // 指向命令行字符串的指针
LPSECURITY_ATTRIBUTES lpProcessAttributes , // 指向进程安全属性的指针
LPSECURITY_ATTRIBUTES lpThreadAttributes , // 指向线程安全属性的指针
BOOL bInheritHandles , // 新进程继承句柄
DWORD dwCreationFlags , // 创建标志
LPVOID lpEnvironment , // 指向新环境块的指针
LPCTSTR lpCurrentDirectory , // 指向当前目录名的指针
LPSTARTUPINFO lpStartupInfo , // 指向 STARTUPINFO 的指针
LPPROCESS_INFORMATION lpProcessInformation // 指向 PROCESS_INFORMATION 的指针
);

hToken

处理代表用户的主要 hToken 。由 hToken 表示的用户必须具有对 lpApplicationName lpCommandLine 参数指定的应用程序的读取和执行访问权限。

如果您的进程具有 SE_TCB_NAME 权限,它可以调用 LogonUser 函数来获取代表指定用户的主要 hToken

或者,您可以调用 DuplicateTokenEx 函数将模拟 hToken 转换为主要 hToken 。这允许模拟客户端的服务器应用程序创建具有客户端安全上下文的进程。

的的其它参数 CreateProcessAsUser 函数表现就像的类似参数 的CreateProcess 功能。

指向一个以空字符结尾的字符串,指定要执行的模块的完整路径和文件名。如果指定了部分名称,则默认使用当前驱动器和当前目录。如果此参数为 NULL,则模块名称必须是 lpCommandLine 字符串中的第一个以空格分隔的标记。指定的模块可以是基于 Win32 的应用程序,也可以是其他类型的模块(例如,MS-DOS 或 OS/2),前提是本地计算机上有适当的子系统。

lp命令行

指向一个以空字符结尾的字符串,指定要执行的应用程序的命令行。如果此参数为 NULL,则 lpApplicationName 字符串用作命令行。如果 lpApplicationName lpCommandLine 都不为 NULL,则 lpApplicationName 指定要执行的模块, lpCommandLine 用作命令行。新进程可以使用 GetCommandLine 检索整个命令行;或 C 运行时进程可以使用 argc / argv 机制。

如果 lpApplicationName 为 NULL,则命令行的第一个以空格分隔的标记指定模块名称。如果文件名不包含扩展名,则假定为 .EXE。如果文件名以句点 (.) 结尾且没有扩展名,或者文件名包含路径,则不会附加 .EXE。如果文件名不包含目录路径,Windows 将按以下顺序搜索可执行文件:

  1. 应用程序加载的目录。

  2. 当前目录。

  3. 32 位 Windows 系统目录。使用 GetSystemDirectory 函数获取该目录的路径。该目录的名称是 SYSTEM32。

  4. 16 位 Windows 系统目录。没有Win32函数获取这个目录的路径,而是搜索了。此目录的名称是 SYSTEM。

  5. Windows 目录。使用 GetWindowsDirectory 函数来获取这个目录的路径。

  6. PATH 环境变量中列出的目录。

如果要创建的进程是基于 MS-DOS

或 16 位 Windows 的应用程序, lpCommandLine 应该是一个完整的命令行,其中第一个元素是应用程序名称。因为这也适用于基于 Win32 的应用程序,所以它是设置 lpCommandLine 的最可靠的方法。

lpProcessAttributes

指向 SECURITY_ATTRIBUTES 的 指针为新进程指定安全描述符并确定子进程是否可以继承返回的句柄的结构。如果 lpProcessAttributes 为 NULL,则进程获得一个默认的安全描述符并且句柄不能被继承。

lpThread属性

指向 SECURITY_ATTRIBUTES 的 指针为新进程指定安全描述符并确定子进程是否可以继承返回的句柄的结构。如果 lpThreadAttributes 为 NULL,则线程获得一个默认的安全描述符并且句柄不能被继承。

bInheritHandles

指示新进程是否从调用进程继承句柄。如果为 TRUE,则调用进程中的每个可继承打开句柄都由新进程继承。继承的句柄与原始句柄具有相同的值和访问权限。

dwCreationFlags

指定控制优先级类和进程创建的附加标志。可以以任意组合指定以下创建标志,除非另有说明:

价值 意义
CREATE_DEFAULT_ERROR_MODE
新进程不继承调用进程的错误模式。相反, CreateProcessAsUser 为新进程提供当前默认错误模式。应用程序通过调用 SetErrorMode 设置当前默认错误模式.
此标志对于在禁用硬错误的情况下运行的多线程 shell 应用程序特别有用。 CreateProcessAsUser
的默认行为是新进程继承调用者的错误模式。设置此标志会更改默认行为。
CREATE_NEW_CONSOLE
新进程有一个新的控制台,而不是继承父级的控制台。此标志不能与 DETACHED_PROCESS 标志一起使用。
CREATE_NEW_PROCESS_GROUP
新进程是新进程组的根进程。进程组包括作为此根进程的后代的所有进程。新进程组的进程标识与 lpProcessInformation 参数中返回的进程标识相同。 GenerateConsoleCtrlEvent 使用进程组 启用向一组控制台进程发送 CTRL+C 或 CTRL+BREAK 信号的功能。
CREATE_SEPARATE_WOW_VDM
此标志仅在启动 16 位 Windows 程序时有效。如果设置,新进程将在私有虚拟 DOS 机 (VDM) 中运行。默认情况下,所有 16 位 Windows 程序都在单个共享 VDM 中运行。单独运行的好处是崩溃只会杀死单个 VDM;在不同 VDM 中运行的任何其他程序继续正常运行。此外,在单独的 VDM 中运行的 16 位 Windows 应用程序具有单独的输入队列。这意味着,如果一个应用程序暂时挂起,单独 VDM 中的应用程序将继续接收输入。
CREATE_SUSPENDED
新进程的主线程创建时处于挂起状态,直到 ResumeThread 才运行 函数被调用。
CREATE_UNICODE_ENVIRONMENT
如果设置, lpEnvironment 指向的环境块使用 Unicode 字符。如果清除,则环境块使用 ANSI 字符。
DEBUG_PROCESS
如果设置,则调用进程被视为调试器,新进程是被调试的进程。系统将在被调试进程中发生的所有调试事件通知调试器。
DEBUG_ONLY_THIS_PROCESS
如果未设置并且正在调试调用进程,则新进程将成为调用进程的调试器正在调试的另一个进程。如果调用进程不是正在调试的进程,则不会发生与调试相关的操作。
DETACHED_PROCESS
对于控制台进程,新进程无权访问父进程的控制台。新进程可以调用 AllocConsole 稍后再创建一个新的控制台。此标志不能与 CREATE_NEW_CONSOLE 标志一起使用。

dwCreationFlags 参数还控制新进程的优先级,这是在确定进程的线程调度优先级使用。如果没有指定以下优先级类标志,则优先级类默认为 NORMAL_PRIORITY_CLASS , 除非创建进程的优先级类是 IDLE_PRIORITY_CLASS 。在这种情况下,子进程的默认优先级类是 IDLE_PRIORITY_CLASS 。可以指定以下标志之一:

优先 意义
HIGH_PRIORITY_CLASS 表示执行时间关键任务的进程必须立即执行才能正确运行。高优先级进程的线程抢占普通优先级或空闲优先级进程的线程。一个例子是 Windows 任务列表,它必须在用户调用时快速响应,而不管操作系统的负载如何。使用高优先级类时要格外小心,因为高优先级类 CPU 密集型应用程序几乎可以使用所有可用周期。
IDLE_PRIORITY_CLASS 表示一个进程,其线程仅在系统空闲时运行,并被运行在更高优先级类中的任何进程的线程抢占。一个例子是屏幕保护程序。空闲优先级类由子进程继承。
NORMAL_PRIORITY_CLASS 表示没有特殊调度需求的正常进程。
REALTIME_PRIORITY_CLASS 表示具有最高优先级的进程。实时优先级进程的线程抢占所有其他进程的线程,包括执行重要任务的操作系统进程。例如,执行时间超过很短时间间隔的实时进程可能会导致磁盘缓存不刷新或导致鼠标无响应。

指向新进程的环境块。如果此参数为 NULL,则新进程使用调用进程的环境。

环境块由空终止字符串的空终止块组成。每个字符串的格式如下:

因为等号用作分隔符,所以不能在环境变量的名称中使用它。

如果应用程序提供环境块,而不是为此参数传递 NULL,则系统驱动器的当前目录信息不会自动传播到新进程。有关这种情况以及如何处理的讨论,请参阅以下备注部分。

环境块可以包含 Unicode 或 ANSI 字符。如果 lpEnvironment 指向的环境块包含 Unicode 字符,则 dwCreationFlags 字段的 CREATE_UNICODE_ENVIRONMENT 标志将被设置。如果块包含 ANSI 字符,则该标志将被清除。

请注意,ANSI 环境块由两个零字节终止:一个用于最后一个字符串,另一个用于终止块。Unicode 环境块由四个零字节终止:两个用于最后一个字符串,另外两个用于终止块。

lp当前目录

指向一个以空字符结尾的字符串,该字符串指定新进程的当前驱动器和目录。该字符串必须是包含驱动器号的完整路径和文件名。如果此参数为 NULL,则使用与调用进程相同的当前驱动器和目录创建新进程。此选项主要用于需要启动应用程序并指定其初始驱动器和工作目录的 shell。

指向一个 STARTUPINFO 指定新进程的主窗口应如何显示的结构。

lp进程信息

指向 PROCESS_INFORMATION 接收有关新进程的标识信息的结构。

如果函数成功,则返回值非零。

如果函数失败,则返回值为零。要获取扩展错误信息,请调用 GetLastError .

CreateProcessAsUser 功能需要SE_ASSIGNPRIMARYTOKEN_NAME和SE_INCREASE_QUOTA_NAME特权。如果它们尚未启用,则 CreateProcessAsUser 在调用期间启用它们。

默认情况下, CreateProcessAsUser 在桌面不可见且无法接收用户输入的非交互式窗口站上创建新进程。要启用用户与新进程的交互,您必须在 STARTUPINFO lpDesktop 成员中指定默认交互式窗口站和桌面的名称“winsta0\default”结构体。此外,在调用 CreateProcessAsUser 之前,您必须更改默认交互式窗口站和默认桌面的自由访问控制列表 (DACL)。窗口站和桌面的 DACL 必须授予 hToken 参数代表的用户访问权限。

CreateProcessAsUser 不会将指定用户的配置文件加载到 HKEY_USERS 注册表项中。这意味着访问 HKEY_CURRENT_USER 注册表项中的信息可能不会产生与正常交互式登录一致的结果。您有责任在调用 CreateProcessAsUser 之前将用户的注册表配置单元加载到 HKEY_USERS 中。

如果 lpEnvironment 参数为 NULL,则新进程继承调用进程的环境。 CreateProcessAsUser 不会自动修改环境块以包含特定于由 hToken 表示的用户的环境变量。例如,如果 lpEnvironment 为 NULL ,则 USERNAME 和 USERDOMAIN 变量是从调用进程继承的。您有责任为新进程准备环境块并在 lpEnvironment 中 指定它。

CreateProcessAsUser 允许您在调用者或目标用户的安全上下文中访问指定的目录和可执行映像。默认情况下, CreateProcessAsUser 访问调用者安全上下文中的目录和可执行映像。在这种情况下,如果调用者无权访问目录和可执行映像,则该函数将失败。要使用目标用户的安全上下文访问目录和可执行映像,请在对 ImpersonateLoggedOnUser 的调用中指定 hToken 调用 CreateProcessAsUser 之前的函数。

新进程和新线程句柄是使用完全访问权限(PROCESS_ALL_ACCESS 和 THREAD_ALL_ACCESS)创建的。对于任一句柄,如果未提供安全描述符,则可以在需要该类型对象句柄的任何函数中使用该句柄。如果提供了安全描述符,则在授予访问权限之前,将对句柄的所有后续使用执行访问检查。如果访问检查拒绝访问,则请求进程无法使用句柄来访问进程或线程。

如果 lpProcessAttributes 参数为 NULL,则将使用 hToken 参数中引用的用户的默认安全描述符。此安全描述符可能不允许调用者访问,在这种情况下,一旦运行该进程可能不会再次打开。 PROCESS_INFORMATION 中 返回的句柄结构有效并将继续拥有所有访问权限。对于线程属性也是如此。

在把手 PROCESS_INFORMATION 必须关闭 CloseHandle的 当不再需要它们时。

该进程被分配了一个进程标识符。该标识符在进程终止之前一直有效。它可以用来标识进程,或者在 OpenProcess 中 指定函数打开进程的句柄。进程中的初始线程也被分配了一个线程标识符。该标识符在线程终止之前一直有效,可用于唯一标识系统内的线程。这些标识符在 PROCESS_INFORMATION 结构中返回。

lpApplicationName lpCommandLine 字符串中指定应用程序名称时,应用程序名称是否包含文件扩展名无关紧要,但有一个例外:

图片/WIN3200090000.gif 文件扩展名为 .COM 的基于MS-DOS或基于 Windows 的应用程序必须包含 . COM 扩展名。

调用线程可以使用 WaitForInputIdle 函数等待新进程完成其初始化并等待用户输入,而没有输入未决。这对于父进程和子进程之间的同步很有用,因为 CreateProcessAsUser 无需等待新进程完成其初始化就返回。例如,创建进程会在尝试查找与新进程关联的窗口之前使用 WaitForInputIdle

关闭进程的首选方法是使用 ExitProcess 函数,因为该函数通知所有附加到即将终止的进程的动态链接库 (DLL)。关闭进程的其他方法不会通知附加的 DLL。请注意,当一个线程调用 ExitProcess 时 ,进程的其他线程将被终止,而没有机会执行任何附加代码(包括附加 DLL 的线程终止代码)。

退出进程 , 退出线程 , 创建 线程 , 创建 远程线程 和正在启动的进程(作为 CreateProcessAsUser 调用的结果)在进程内彼此序列化。一次只能发生这些事件之一。这意味着以下限制成立:

  • 在进程启动和 DLL 初始化例程期间,可以创建新线程,但在进程的 DLL 初始化完成之前它们不会开始执行。

  • 一个进程中一次只能有一个线程处于 DLL 初始化或分离例程中。

  • 直到没有线程正在执行 DLL 初始化或分离例程时, ExitProcess 函数才会返回。

该CreateProcessAsUser函数创建一个新的进程及其主线程。新进程然后执行指定的可执行文件。该CreateProcessAsUser功能类似的CreateProcess函数,除了新进程运行在由hToken参数表示的用户的安全上下文中。默认情况下,新进程是非交互式的,即它运行在不可见且无法接收用户输入的桌面上。此外,默认情况下,新进程继承调用进程的环境,而不是与指定用户关联的环境。BOOL CreateProcessAsUser(HANDLEhToken, // 处理代表..
-------- CreateProcess Ex.h文件 -------- #ifndef _CREATE_PROCESS_EX_H_ #define _CREATE_PROCESS_EX_H_ #include  #include "tchar.h" #pragma comment(lib, "shell32") #pragma comment(lib, "us er 32") #pragma co
TCHAR szUs er name[MAX_PATH]; TCHAR para[MAX_PATH] = {0}; TCHAR szUs er namePath[MAX_PATH]; DWORD dwUs er nameLen = MAX_PATH; DWORD cursessionid; cursessionid = WTSGetActiveConso   但却出现了问题,之前产品代码中会调用windows API - CreateProcess AsUs er ,来以另一个账号的身份启动另一个进程,另一个账号是通过UI单独提供的。   之前会成功,但现在却失败,无法启动新进程。   错误码( Er ror Code)是1314,通过查询文档,这个 Er ro
开发中有时会遇到这样的问题,当服务程序需要使用某些功能时,由于用户的关系而受到限制, 比如访问注册表的HKEY_CURRENT_US ER 键,使用网络等等,这时候就需要以当前登陆用户的身份 去进行操作,通常会创建一个进程来完成需要的功能。如果使用 CreateProcess 来创建进程的话, 新创建的进程和服务程序依然是相同的用户身份,还是无法达到目的,只有使用 CreateProcess AsUs er 了。 但 CreateProcess AsUs er 的第一个参数是HANDLE hToken,该参数通常应该用Lo...
using murrayju . ProcessExtensions ; // ... ProcessExtensions . StartProcessAsCurrentUs er ( " calc.exe " ); 第二个参数用于将命令行参数作为字符串传递。 根据目标应用程序,可能期望argv[0]作为可执行文件的名称,或者它可能是第一个参数。 有关详细信息,请参。 如有疑问,请尝试两种方式。 UAC(us er account control),这里科普下UAC的功能,其实UAC就是大家常见的安装软件或者启动程序的时候的出现的全屏变暗的一个提示框,正常的UAC级别下,会检测程序是否有数字签名(可识别程序),以及他的数字签名是否合法,这对于一部分低端的木马具有提醒作用,所以除非特殊情况,不要乱对UCA降权。 UAC运行原理: 在Windows Vista操作系统中。 用户账户主要... 有一个带界面的GUI程序需要一直保持运行状态,但是操作系统有时会自动更新重启,虽然已经通过注册表的方式设置为自启动,但是必须登录操纵系统才能启动,所以需要一种不登录也能让该程序运行的实现方法。 又因为这个程序是GUI程序,无法直接注册为系统服务(系统服务可以开机后不登录也在后台运行),所以考虑通过把一个控制台程序注册成系统服务,然后通过这个控制台程序调用GUI程序。下面代码是控制台程序调用GUI程序的关键逻辑。 经测试,在Win10 和 window... Initialization_: 感谢分享! 个人使用C#调用这个API的时候发现lpApplicationName和lpCommandLine都不为 NULL时,lpCommandLine并没有生效。将lpCommandLine设为NULL将参数加在lpApplicationName中可以正常将启动参数传入。 使用C#的同学可以注意下~ WPF中实现基于物理像素绘图的方法是什么 君子居易: 这里有个问题,将窗体最大化,或者调整窗体大小,GuidelineSet绘制的线粗点,有些线细点。不知道各位大佬有没有什么好的建议保持粗细一致。 不然的话还是比较缺乏应用价值。存在不可控因素。