/// dir\program name.exe</c> If the executable module is a 16-bit application, lpApplicationName should be <c>NULL</c>, and the
/// string pointed to by lpCommandLine should specify the executable module as well as its arguments. By default, all 16-bit
/// Windows-based applications created by <c>CreateProcessAsUser</c> are run in a separate VDM (equivalent to
/// <c>CREATE_SEPARATE_WOW_VDM</c> in CreateProcess).
/// </para>
/// </param>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32K characters. If lpApplicationName is <c>NULL</c>, the
/// module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The Unicode version of this function, <c>CreateProcessAsUserW</c>, can modify the contents of this string. Therefore, this
/// parameter cannot be a pointer to read-only memory (such as a <c>const</c> variable or a literal string). If this parameter is a
/// constant string, the function may cause an access violation.
/// </para>
/// <para>
/// The lpCommandLine parameter can be <c>NULL</c>. In that case, the function uses the string pointed to by lpApplicationName as the
/// command line.
/// </para>
/// <para>
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, *lpApplicationName specifies the module to execute, and
/// *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console
/// processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C
/// programmers generally repeat the module name as the first token in the command line.
/// </para>
/// <para>
/// If lpApplicationName is <c>NULL</c>, the first white space–delimited token of the command line specifies the module name. If you
/// are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin
/// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended.
/// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period
/// (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory
/// path, the system searches for the executable file in the following sequence:
/// </para>
/// <list type="number">
/// <item>
/// <term>The directory from which the application loaded.</term>
/// </item>
/// <item>
/// <term>The current directory for the parent process.</term>
/// </item>
/// <item>
/// <term>The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.</term>
/// </item>
/// <item>
/// <term>The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched.</term>
/// </item>
/// <item>
/// <term>The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.</term>
/// </item>
/// <item>
/// <term>
/// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application
/// path specified by the <c>App Paths</c> registry key. To include this per-application path in the search sequence, use the
/// ShellExecute function.
/// </term>
/// </item>
/// </list>
/// <para>
/// The system adds a null character to the command line string to separate the file name from the arguments. This divides the
/// original string into two strings for internal processing.
/// </para>
/// </param>
/// <param name="lpProcessAttributes">
/// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new process object and determines
/// whether child processes can inherit the returned handle to the process. If lpProcessAttributes is <c>NULL</c> or
/// <c>lpSecurityDescriptor</c> is <c>NULL</c>, the process gets a default security descriptor and the handle cannot be inherited.
/// The default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow
/// access for the caller, in which case the process may not be opened again after it is run. The process handle is valid and will
/// continue to have full access rights.
/// </param>
/// <param name="lpThreadAttributes">
/// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new thread object and determines
/// whether child processes can inherit the returned handle to the thread. If lpThreadAttributes is <c>NULL</c> or
/// <c>lpSecurityDescriptor</c> is <c>NULL</c>, the thread gets a default security descriptor and the handle cannot be inherited. The
/// default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow access
/// for the caller.
/// </param>
/// <param name="bInheritHandles">
/// <para>
/// If this parameter is <c>TRUE</c>, each inheritable handle in the calling process is inherited by the new process. If the
/// parameter is <c>FALSE</c>, the handles are not inherited. Note that inherited handles have the same value and access rights as
/// the original handles.
/// </para>
/// <para>
/// <c>Terminal Services:</c> You cannot inherit handles across sessions. Additionally, if this parameter is <c>TRUE</c>, you must
/// create the process in the same session as the caller.
/// </para>
/// <para>
/// <c>Protected Process Light (PPL) processes:</c> The generic handle inheritance is blocked when a PPL process creates a non-PPL
/// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights
/// </para>
/// </param>
/// <param name="dwCreationFlags">
/// <para>
/// The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.
/// </para>
/// <para>
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the
/// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority
/// class defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
/// </para>
/// </param>
/// <param name="lpEnvironment">
/// <para>
/// A pointer to an environment block for the new process. If this parameter is <c>NULL</c>, the new process uses the environment of
/// the calling process.
/// </para>
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and
/// the environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessAsUserA</c> fails if the total size of the environment block for the process
/// exceeds 32,767 characters.
/// </para>
/// <para>
/// Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A
/// Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.
/// </para>
/// <para>
/// <c>Windows Server 2003 and Windows XP:</c> If the size of the combined user and system environment variable exceeds 8192 bytes,
/// the process created by <c>CreateProcessAsUser</c> no longer runs with the environment block passed to the function by the parent
/// process. Instead, the child process runs with the environment block returned by the CreateEnvironmentBlock function.
/// </para>
/// <para>To retrieve a copy of the environment block for a given user, use the CreateEnvironmentBlock function.</para>
/// </param>
/// <param name="lpCurrentDirectory">
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
/// <para>
/// If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature
/// is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
/// </para>
/// </param>
/// <param name="lpStartupInfo">
/// <para>A pointer to a STARTUPINFO or STARTUPINFOEX structure.</para>
/// <para>
/// The user must have full access to both the specified window station and desktop. If you want the process to be interactive,
/// specify winsta0\default. If the <c>lpDesktop</c> member is NULL, the new process inherits the desktop and window station of its
/// parent process. If this member is an empty string, "", the new process connects to a window station using the rules described in
/// Process Connection to a Window Station.
/// </para>
/// <para>
/// To set extended attributes, use a STARTUPINFOEX structure and specify <c>EXTENDED_STARTUPINFO_PRESENT</c> in the dwCreationFlags parameter.
/// </para>
/// <para>Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.</para>
/// <para>
/// <c>Important</c> The caller is responsible for ensuring that the standard handle fields in STARTUPINFO contain valid handle
/// values. These fields are copied unchanged to the child process without validation, even when the <c>dwFlags</c> member specifies
/// <c>STARTF_USESTDHANDLES</c>. Incorrect values can cause the child process to misbehave or crash. Use the Application Verifier
/// runtime verification tool to detect invalid handles.
/// </para>
/// </param>
/// <param name="lpProcessInformation">
/// <para>A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.</para>
/// <para>Handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer needed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// <para>
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
/// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// <c>CreateProcessAsUser</c> must be able to open the primary token of the calling process with the <c>TOKEN_DUPLICATE</c> and
/// <c>TOKEN_IMPERSONATE</c> access rights.
/// </para>
/// <para>
/// By default, <c>CreateProcessAsUser</c> creates the new process on a noninteractive window station with a desktop that is not
/// visible and cannot receive user input. To enable user interaction with the new process, you must specify the name of the default
/// interactive window station and desktop, "winsta0\default", in the <c>lpDesktop</c> member of the STARTUPINFO structure. In
/// addition, before calling <c>CreateProcessAsUser</c>, you must change the discretionary access control list (DACL) of both the
/// default interactive window station and the default desktop. The DACLs for the window station and desktop must grant access to the
/// user or the logon session represented by the hToken parameter.
/// </para>
/// <para>
/// <c>CreateProcessAsUser</c> does not load the specified user's profile into the <c>HKEY_USERS</c> registry key. Therefore, to
/// access the information in the <c>HKEY_CURRENT_USER</c> registry key, you must load the user's profile information into
/// <c>HKEY_USERS</c> with the LoadUserProfile function before calling <c>CreateProcessAsUser</c>. Be sure to call UnloadUserProfile
/// after the new process exits.
/// </para>
/// <para>
/// If the lpEnvironment parameter is NULL, the new process inherits the environment of the calling process.
/// <c>CreateProcessAsUser</c> does not automatically modify the environment block to include environment variables specific to the
/// user represented by hToken. For example, the USERNAME and USERDOMAIN variables are inherited from the calling process if
/// lpEnvironment is NULL. It is your responsibility to prepare the environment block for the new process and specify it in lpEnvironment.
/// </para>
/// <para>
/// The CreateProcessWithLogonW and CreateProcessWithTokenW functions are similar to <c>CreateProcessAsUser</c>, except that the
/// caller does not need to call the LogonUser function to authenticate the user and get a token.
/// </para>
/// <para>
/// <c>CreateProcessAsUser</c> allows you to access the specified directory and executable image in the security context of the
/// caller or the target user. By default, <c>CreateProcessAsUser</c> accesses the directory and executable image in the security
/// context of the caller. In this case, if the caller does not have access to the directory and executable image, the function
/// fails. To access the directory and executable image using the security context of the target user, specify hToken in a call to
/// the ImpersonateLoggedOnUser function before calling <c>CreateProcessAsUser</c>.
/// </para>
/// <para>
/// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify
/// the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also
/// assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The identifier is
/// valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are
/// returned in the PROCESS_INFORMATION structure.
/// </para>
/// <para>
/// The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is
/// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because
/// <c>CreateProcessAsUser</c> returns without waiting for the new process to finish its initialization. For example, the creating
/// process would use <c>WaitForInputIdle</c> before trying to find a window associated with the new process.
/// </para>
/// <para>
/// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of
/// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached
/// DLLs. Note that when a thread calls <c>ExitProcess</c>, other threads of the process are terminated without an opportunity to
/// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
/// </para>
/// <para>Security Remarks</para>
/// <para>
/// The lpApplicationName parameter can be NULL, in which case the executable name must be the first white space–delimited string in
/// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because
/// of the way the function parses spaces. The following example is dangerous because the function will attempt to run "Program.exe",
/// if it exists, instead of "MyApp.exe".
/// </para>
/// <para>
/// If a malicious user were to create an application called "Program.exe" on a system, any program that incorrectly calls
/// <c>CreateProcessAsUser</c> using the Program Files directory will run this application instead of the intended application.
/// </para>
/// <para>
/// To avoid this problem, do not pass NULL for lpApplicationName. If you do pass <c>NULL</c> for lpApplicationName, use quotation
/// marks around the executable path in lpCommandLine, as shown in the example below.
/// </para>
/// <para>
/// <c>PowerShell:</c> When the <c>CreateProcessAsUser</c> function is used to implement a cmdlet in PowerShell version 2.0, the
/// cmdlet operates correctly for both fan-in and fan-out remote sessions. Because of certain security scenarios, however, a cmdlet
/// implemented with <c>CreateProcessAsUser</c> only operates correctly in PowerShell version 3.0 for fan-in remote sessions; fan-out
/// remote sessions will fail because of insufficient client security privileges. To implement a cmdlet that works for both fan-in
/// and fan-out remote sessions in PowerShell version 3.0, use the CreateProcess function.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Starting an Interactive Client Process.</para>
/// dir\program name.exe</c> If the executable module is a 16-bit application, lpApplicationName should be <c>NULL</c>, and the
/// string pointed to by lpCommandLine should specify the executable module as well as its arguments. By default, all 16-bit
/// Windows-based applications created by <c>CreateProcessAsUser</c> are run in a separate VDM (equivalent to
/// <c>CREATE_SEPARATE_WOW_VDM</c> in CreateProcess).
/// </para>
/// </param>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32K characters. If lpApplicationName is <c>NULL</c>, the
/// module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The Unicode version of this function, <c>CreateProcessAsUserW</c>, can modify the contents of this string. Therefore, this
/// parameter cannot be a pointer to read-only memory (such as a <c>const</c> variable or a literal string). If this parameter is a
/// constant string, the function may cause an access violation.
/// </para>
/// <para>
/// The lpCommandLine parameter can be <c>NULL</c>. In that case, the function uses the string pointed to by lpApplicationName as the
/// command line.
/// </para>
/// <para>
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, *lpApplicationName specifies the module to execute, and
/// *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console
/// processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C
/// programmers generally repeat the module name as the first token in the command line.
/// </para>
/// <para>
/// If lpApplicationName is <c>NULL</c>, the first white space–delimited token of the command line specifies the module name. If you
/// are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin
/// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended.
/// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period
/// (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory
/// path, the system searches for the executable file in the following sequence:
/// </para>
/// <list type="number">
/// <item>
/// <term>The directory from which the application loaded.</term>
/// </item>
/// <item>
/// <term>The current directory for the parent process.</term>
/// </item>
/// <item>
/// <term>The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.</term>
/// </item>
/// <item>
/// <term>The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched.</term>
/// </item>
/// <item>
/// <term>The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.</term>
/// </item>
/// <item>
/// <term>
/// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application
/// path specified by the <c>App Paths</c> registry key. To include this per-application path in the search sequence, use the
/// ShellExecute function.
/// </term>
/// </item>
/// </list>
/// <para>
/// The system adds a null character to the command line string to separate the file name from the arguments. This divides the
/// original string into two strings for internal processing.
/// </para>
/// </param>
/// <param name="lpProcessAttributes">
/// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new process object and determines
/// whether child processes can inherit the returned handle to the process. If lpProcessAttributes is <c>NULL</c> or
/// <c>lpSecurityDescriptor</c> is <c>NULL</c>, the process gets a default security descriptor and the handle cannot be inherited.
/// The default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow
/// access for the caller, in which case the process may not be opened again after it is run. The process handle is valid and will
/// continue to have full access rights.
/// </param>
/// <param name="lpThreadAttributes">
/// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new thread object and determines
/// whether child processes can inherit the returned handle to the thread. If lpThreadAttributes is <c>NULL</c> or
/// <c>lpSecurityDescriptor</c> is <c>NULL</c>, the thread gets a default security descriptor and the handle cannot be inherited. The
/// default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow access
/// for the caller.
/// </param>
/// <param name="bInheritHandles">
/// <para>
/// If this parameter is <c>TRUE</c>, each inheritable handle in the calling process is inherited by the new process. If the
/// parameter is <c>FALSE</c>, the handles are not inherited. Note that inherited handles have the same value and access rights as
/// the original handles.
/// </para>
/// <para>
/// <c>Terminal Services:</c> You cannot inherit handles across sessions. Additionally, if this parameter is <c>TRUE</c>, you must
/// create the process in the same session as the caller.
/// </para>
/// <para>
/// <c>Protected Process Light (PPL) processes:</c> The generic handle inheritance is blocked when a PPL process creates a non-PPL
/// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights
/// </para>
/// </param>
/// <param name="dwCreationFlags">
/// <para>
/// The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.
/// </para>
/// <para>
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the
/// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority
/// class defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
/// </para>
/// </param>
/// <param name="lpEnvironment">
/// <para>
/// A pointer to an environment block for the new process. If this parameter is <c>NULL</c>, the new process uses the environment of
/// the calling process.
/// </para>
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and
/// the environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessAsUserA</c> fails if the total size of the environment block for the process
/// exceeds 32,767 characters.
/// </para>
/// <para>
/// Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A
/// Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.
/// </para>
/// <para>
/// <c>Windows Server 2003 and Windows XP:</c> If the size of the combined user and system environment variable exceeds 8192 bytes,
/// the process created by <c>CreateProcessAsUser</c> no longer runs with the environment block passed to the function by the parent
/// process. Instead, the child process runs with the environment block returned by the CreateEnvironmentBlock function.
/// </para>
/// <para>To retrieve a copy of the environment block for a given user, use the CreateEnvironmentBlock function.</para>
/// </param>
/// <param name="lpCurrentDirectory">
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
/// <para>
/// If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature
/// is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
/// </para>
/// </param>
/// <param name="lpStartupInfo">
/// <para>A pointer to a STARTUPINFO or STARTUPINFOEX structure.</para>
/// <para>
/// The user must have full access to both the specified window station and desktop. If you want the process to be interactive,
/// specify winsta0\default. If the <c>lpDesktop</c> member is NULL, the new process inherits the desktop and window station of its
/// parent process. If this member is an empty string, "", the new process connects to a window station using the rules described in
/// Process Connection to a Window Station.
/// </para>
/// <para>
/// To set extended attributes, use a STARTUPINFOEX structure and specify <c>EXTENDED_STARTUPINFO_PRESENT</c> in the dwCreationFlags parameter.
/// </para>
/// <para>Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.</para>
/// <para>
/// <c>Important</c> The caller is responsible for ensuring that the standard handle fields in STARTUPINFO contain valid handle
/// values. These fields are copied unchanged to the child process without validation, even when the <c>dwFlags</c> member specifies
/// <c>STARTF_USESTDHANDLES</c>. Incorrect values can cause the child process to misbehave or crash. Use the Application Verifier
/// runtime verification tool to detect invalid handles.
/// </para>
/// </param>
/// <param name="lpProcessInformation">
/// <para>A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.</para>
/// <para>Handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer needed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// <para>
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
/// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// <c>CreateProcessAsUser</c> must be able to open the primary token of the calling process with the <c>TOKEN_DUPLICATE</c> and
/// <c>TOKEN_IMPERSONATE</c> access rights.
/// </para>
/// <para>
/// By default, <c>CreateProcessAsUser</c> creates the new process on a noninteractive window station with a desktop that is not
/// visible and cannot receive user input. To enable user interaction with the new process, you must specify the name of the default
/// interactive window station and desktop, "winsta0\default", in the <c>lpDesktop</c> member of the STARTUPINFO structure. In
/// addition, before calling <c>CreateProcessAsUser</c>, you must change the discretionary access control list (DACL) of both the
/// default interactive window station and the default desktop. The DACLs for the window station and desktop must grant access to the
/// user or the logon session represented by the hToken parameter.
/// </para>
/// <para>
/// <c>CreateProcessAsUser</c> does not load the specified user's profile into the <c>HKEY_USERS</c> registry key. Therefore, to
/// access the information in the <c>HKEY_CURRENT_USER</c> registry key, you must load the user's profile information into
/// <c>HKEY_USERS</c> with the LoadUserProfile function before calling <c>CreateProcessAsUser</c>. Be sure to call UnloadUserProfile
/// after the new process exits.
/// </para>
/// <para>
/// If the lpEnvironment parameter is NULL, the new process inherits the environment of the calling process.
/// <c>CreateProcessAsUser</c> does not automatically modify the environment block to include environment variables specific to the
/// user represented by hToken. For example, the USERNAME and USERDOMAIN variables are inherited from the calling process if
/// lpEnvironment is NULL. It is your responsibility to prepare the environment block for the new process and specify it in lpEnvironment.
/// </para>
/// <para>
/// The CreateProcessWithLogonW and CreateProcessWithTokenW functions are similar to <c>CreateProcessAsUser</c>, except that the
/// caller does not need to call the LogonUser function to authenticate the user and get a token.
/// </para>
/// <para>
/// <c>CreateProcessAsUser</c> allows you to access the specified directory and executable image in the security context of the
/// caller or the target user. By default, <c>CreateProcessAsUser</c> accesses the directory and executable image in the security
/// context of the caller. In this case, if the caller does not have access to the directory and executable image, the function
/// fails. To access the directory and executable image using the security context of the target user, specify hToken in a call to
/// the ImpersonateLoggedOnUser function before calling <c>CreateProcessAsUser</c>.
/// </para>
/// <para>
/// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify
/// the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also
/// assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The identifier is
/// valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are
/// returned in the PROCESS_INFORMATION structure.
/// </para>
/// <para>
/// The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is
/// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because
/// <c>CreateProcessAsUser</c> returns without waiting for the new process to finish its initialization. For example, the creating
/// process would use <c>WaitForInputIdle</c> before trying to find a window associated with the new process.
/// </para>
/// <para>
/// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of
/// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached
/// DLLs. Note that when a thread calls <c>ExitProcess</c>, other threads of the process are terminated without an opportunity to
/// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
/// </para>
/// <para>Security Remarks</para>
/// <para>
/// The lpApplicationName parameter can be NULL, in which case the executable name must be the first white space–delimited string in
/// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because
/// of the way the function parses spaces. The following example is dangerous because the function will attempt to run "Program.exe",
/// if it exists, instead of "MyApp.exe".
/// </para>
/// <para>
/// If a malicious user were to create an application called "Program.exe" on a system, any program that incorrectly calls
/// <c>CreateProcessAsUser</c> using the Program Files directory will run this application instead of the intended application.
/// </para>
/// <para>
/// To avoid this problem, do not pass NULL for lpApplicationName. If you do pass <c>NULL</c> for lpApplicationName, use quotation
/// marks around the executable path in lpCommandLine, as shown in the example below.
/// </para>
/// <para>
/// <c>PowerShell:</c> When the <c>CreateProcessAsUser</c> function is used to implement a cmdlet in PowerShell version 2.0, the
/// cmdlet operates correctly for both fan-in and fan-out remote sessions. Because of certain security scenarios, however, a cmdlet
/// implemented with <c>CreateProcessAsUser</c> only operates correctly in PowerShell version 3.0 for fan-in remote sessions; fan-out
/// remote sessions will fail because of insufficient client security privileges. To implement a cmdlet that works for both fan-in
/// and fan-out remote sessions in PowerShell version 3.0, use the CreateProcess function.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Starting an Interactive Client Process.</para>
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and
/// the environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessAsUserA</c> fails if the total size of the environment block for the process
/// exceeds 32,767 characters.
/// </para>
/// <para>
/// Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A
/// Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.
/// </para>
/// <para>
/// <c>Windows Server 2003 and Windows XP:</c> If the size of the combined user and system environment variable exceeds 8192 bytes,
/// the process created by <c>CreateProcessAsUser</c> no longer runs with the environment block passed to the function by the parent
/// process. Instead, the child process runs with the environment block returned by the CreateEnvironmentBlock function.
/// </para>
/// <para>To retrieve a copy of the environment block for a given user, use the CreateEnvironmentBlock function.</para>
/// dir\program name.exe</c> If the executable module is a 16-bit application, lpApplicationName should be <c>NULL</c>, and the
/// string pointed to by lpCommandLine should specify the executable module as well as its arguments. By default, all 16-bit
/// Windows-based applications created by <c>CreateProcessAsUser</c> are run in a separate VDM (equivalent to
/// <c>CREATE_SEPARATE_WOW_VDM</c> in CreateProcess).
/// </para>
/// </param>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32K characters. If lpApplicationName is <c>NULL</c>, the
/// module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The Unicode version of this function, <c>CreateProcessAsUserW</c>, can modify the contents of this string. Therefore, this
/// parameter cannot be a pointer to read-only memory (such as a <c>const</c> variable or a literal string). If this parameter is a
/// constant string, the function may cause an access violation.
/// </para>
/// <para>
/// The lpCommandLine parameter can be <c>NULL</c>. In that case, the function uses the string pointed to by lpApplicationName as the
/// command line.
/// </para>
/// <para>
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, *lpApplicationName specifies the module to execute, and
/// *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console
/// processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C
/// programmers generally repeat the module name as the first token in the command line.
/// </para>
/// <para>
/// If lpApplicationName is <c>NULL</c>, the first white space–delimited token of the command line specifies the module name. If you
/// are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin
/// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended.
/// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period
/// (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory
/// path, the system searches for the executable file in the following sequence:
/// </para>
/// <list type="number">
/// <item>
/// <term>The directory from which the application loaded.</term>
/// </item>
/// <item>
/// <term>The current directory for the parent process.</term>
/// </item>
/// <item>
/// <term>The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.</term>
/// </item>
/// <item>
/// <term>The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched.</term>
/// </item>
/// <item>
/// <term>The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.</term>
/// </item>
/// <item>
/// <term>
/// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application
/// path specified by the <c>App Paths</c> registry key. To include this per-application path in the search sequence, use the
/// ShellExecute function.
/// </term>
/// </item>
/// </list>
/// <para>
/// The system adds a null character to the command line string to separate the file name from the arguments. This divides the
/// original string into two strings for internal processing.
/// </para>
/// </param>
/// <param name="lpProcessAttributes">
/// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new process object and determines
/// whether child processes can inherit the returned handle to the process. If lpProcessAttributes is <c>NULL</c> or
/// <c>lpSecurityDescriptor</c> is <c>NULL</c>, the process gets a default security descriptor and the handle cannot be inherited.
/// The default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow
/// access for the caller, in which case the process may not be opened again after it is run. The process handle is valid and will
/// continue to have full access rights.
/// </param>
/// <param name="lpThreadAttributes">
/// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new thread object and determines
/// whether child processes can inherit the returned handle to the thread. If lpThreadAttributes is <c>NULL</c> or
/// <c>lpSecurityDescriptor</c> is <c>NULL</c>, the thread gets a default security descriptor and the handle cannot be inherited. The
/// default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow access
/// for the caller.
/// </param>
/// <param name="bInheritHandles">
/// <para>
/// If this parameter is <c>TRUE</c>, each inheritable handle in the calling process is inherited by the new process. If the
/// parameter is <c>FALSE</c>, the handles are not inherited. Note that inherited handles have the same value and access rights as
/// the original handles.
/// </para>
/// <para>
/// <c>Terminal Services:</c> You cannot inherit handles across sessions. Additionally, if this parameter is <c>TRUE</c>, you must
/// create the process in the same session as the caller.
/// </para>
/// <para>
/// <c>Protected Process Light (PPL) processes:</c> The generic handle inheritance is blocked when a PPL process creates a non-PPL
/// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights
/// </para>
/// </param>
/// <param name="dwCreationFlags">
/// <para>
/// The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.
/// </para>
/// <para>
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the
/// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority
/// class defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
/// </para>
/// </param>
/// <param name="lpEnvironment">
/// <para>
/// A pointer to an environment block for the new process. If this parameter is <c>NULL</c>, the new process uses the environment of
/// the calling process.
/// </para>
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and
/// the environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessAsUserA</c> fails if the total size of the environment block for the process
/// exceeds 32,767 characters.
/// </para>
/// <para>
/// Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A
/// Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.
/// </para>
/// <para>
/// <c>Windows Server 2003 and Windows XP:</c> If the size of the combined user and system environment variable exceeds 8192 bytes,
/// the process created by <c>CreateProcessAsUser</c> no longer runs with the environment block passed to the function by the parent
/// process. Instead, the child process runs with the environment block returned by the CreateEnvironmentBlock function.
/// </para>
/// <para>To retrieve a copy of the environment block for a given user, use the CreateEnvironmentBlock function.</para>
/// </param>
/// <param name="lpCurrentDirectory">
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
/// <para>
/// If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature
/// is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
/// </para>
/// </param>
/// <param name="lpStartupInfo">
/// <para>A pointer to a STARTUPINFO or STARTUPINFOEX structure.</para>
/// <para>
/// The user must have full access to both the specified window station and desktop. If you want the process to be interactive,
/// specify winsta0\default. If the <c>lpDesktop</c> member is NULL, the new process inherits the desktop and window station of its
/// parent process. If this member is an empty string, "", the new process connects to a window station using the rules described in
/// Process Connection to a Window Station.
/// </para>
/// <para>
/// To set extended attributes, use a STARTUPINFOEX structure and specify <c>EXTENDED_STARTUPINFO_PRESENT</c> in the dwCreationFlags parameter.
/// </para>
/// <para>Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.</para>
/// <para>
/// <c>Important</c> The caller is responsible for ensuring that the standard handle fields in STARTUPINFO contain valid handle
/// values. These fields are copied unchanged to the child process without validation, even when the <c>dwFlags</c> member specifies
/// <c>STARTF_USESTDHANDLES</c>. Incorrect values can cause the child process to misbehave or crash. Use the Application Verifier
/// runtime verification tool to detect invalid handles.
/// </para>
/// </param>
/// <param name="lpProcessInformation">
/// <para>A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.</para>
/// <para>Handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer needed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// <para>
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
/// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// <c>CreateProcessAsUser</c> must be able to open the primary token of the calling process with the <c>TOKEN_DUPLICATE</c> and
/// <c>TOKEN_IMPERSONATE</c> access rights.
/// </para>
/// <para>
/// By default, <c>CreateProcessAsUser</c> creates the new process on a noninteractive window station with a desktop that is not
/// visible and cannot receive user input. To enable user interaction with the new process, you must specify the name of the default
/// interactive window station and desktop, "winsta0\default", in the <c>lpDesktop</c> member of the STARTUPINFO structure. In
/// addition, before calling <c>CreateProcessAsUser</c>, you must change the discretionary access control list (DACL) of both the
/// default interactive window station and the default desktop. The DACLs for the window station and desktop must grant access to the
/// user or the logon session represented by the hToken parameter.
/// </para>
/// <para>
/// <c>CreateProcessAsUser</c> does not load the specified user's profile into the <c>HKEY_USERS</c> registry key. Therefore, to
/// access the information in the <c>HKEY_CURRENT_USER</c> registry key, you must load the user's profile information into
/// <c>HKEY_USERS</c> with the LoadUserProfile function before calling <c>CreateProcessAsUser</c>. Be sure to call UnloadUserProfile
/// after the new process exits.
/// </para>
/// <para>
/// If the lpEnvironment parameter is NULL, the new process inherits the environment of the calling process.
/// <c>CreateProcessAsUser</c> does not automatically modify the environment block to include environment variables specific to the
/// user represented by hToken. For example, the USERNAME and USERDOMAIN variables are inherited from the calling process if
/// lpEnvironment is NULL. It is your responsibility to prepare the environment block for the new process and specify it in lpEnvironment.
/// </para>
/// <para>
/// The CreateProcessWithLogonW and CreateProcessWithTokenW functions are similar to <c>CreateProcessAsUser</c>, except that the
/// caller does not need to call the LogonUser function to authenticate the user and get a token.
/// </para>
/// <para>
/// <c>CreateProcessAsUser</c> allows you to access the specified directory and executable image in the security context of the
/// caller or the target user. By default, <c>CreateProcessAsUser</c> accesses the directory and executable image in the security
/// context of the caller. In this case, if the caller does not have access to the directory and executable image, the function
/// fails. To access the directory and executable image using the security context of the target user, specify hToken in a call to
/// the ImpersonateLoggedOnUser function before calling <c>CreateProcessAsUser</c>.
/// </para>
/// <para>
/// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify
/// the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also
/// assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The identifier is
/// valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are
/// returned in the PROCESS_INFORMATION structure.
/// </para>
/// <para>
/// The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is
/// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because
/// <c>CreateProcessAsUser</c> returns without waiting for the new process to finish its initialization. For example, the creating
/// process would use <c>WaitForInputIdle</c> before trying to find a window associated with the new process.
/// </para>
/// <para>
/// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of
/// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached
/// DLLs. Note that when a thread calls <c>ExitProcess</c>, other threads of the process are terminated without an opportunity to
/// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
/// </para>
/// <para>Security Remarks</para>
/// <para>
/// The lpApplicationName parameter can be NULL, in which case the executable name must be the first white space–delimited string in
/// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because
/// of the way the function parses spaces. The following example is dangerous because the function will attempt to run "Program.exe",
/// if it exists, instead of "MyApp.exe".
/// </para>
/// <para>
/// If a malicious user were to create an application called "Program.exe" on a system, any program that incorrectly calls
/// <c>CreateProcessAsUser</c> using the Program Files directory will run this application instead of the intended application.
/// </para>
/// <para>
/// To avoid this problem, do not pass NULL for lpApplicationName. If you do pass <c>NULL</c> for lpApplicationName, use quotation
/// marks around the executable path in lpCommandLine, as shown in the example below.
/// </para>
/// <para>
/// <c>PowerShell:</c> When the <c>CreateProcessAsUser</c> function is used to implement a cmdlet in PowerShell version 2.0, the
/// cmdlet operates correctly for both fan-in and fan-out remote sessions. Because of certain security scenarios, however, a cmdlet
/// implemented with <c>CreateProcessAsUser</c> only operates correctly in PowerShell version 3.0 for fan-in remote sessions; fan-out
/// remote sessions will fail because of insufficient client security privileges. To implement a cmdlet that works for both fan-in
/// and fan-out remote sessions in PowerShell version 3.0, use the CreateProcess function.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Starting an Interactive Client Process.</para>