private static extern bool CreateProcessWithTokenW(
     IntPtr hToken,
     LogonFlags dwLogonFlags,
     [MarshalAs(UnmanagedType.LPTStr)]
     string lpApplicationName,
     StringBuilder lpCommandLine,
     CreationFlags dwCreationFlags,
     IntPtr lpEnvironment,
     [MarshalAs(UnmanagedType.LPTStr)]
     string lpCurrentDirectory,
     STARTUPINFOEX lpStartupInfo,
     out PROCESS_INFORMATION lpProcessInformation);
        public static CommandResult RunAsUser(string username, string password, string lpCommandLine,
                                              string lpCurrentDirectory, string stdinInput, LogonFlags logonFlags, LogonType logonType)
        {
            SecurityIdentifier account = null;

            if (logonType != LogonType.LOGON32_LOGON_NEW_CREDENTIALS)
            {
                account = GetBecomeSid(username);
            }

            STARTUPINFOEX si = new STARTUPINFOEX();

            si.startupInfo.dwFlags = (int)StartupInfoFlags.USESTDHANDLES;

            SECURITY_ATTRIBUTES pipesec = new SECURITY_ATTRIBUTES();

            pipesec.bInheritHandle = true;

            // Create the stdout, stderr and stdin pipes used in the process and add to the startupInfo
            SafeFileHandle stdout_read, stdout_write, stderr_read, stderr_write, stdin_read, stdin_write;

            if (!CreatePipe(out stdout_read, out stdout_write, pipesec, 0))
            {
                throw new Win32Exception("STDOUT pipe setup failed");
            }
            if (!SetHandleInformation(stdout_read, HandleFlags.INHERIT, 0))
            {
                throw new Win32Exception("STDOUT pipe handle setup failed");
            }

            if (!CreatePipe(out stderr_read, out stderr_write, pipesec, 0))
            {
                throw new Win32Exception("STDERR pipe setup failed");
            }
            if (!SetHandleInformation(stderr_read, HandleFlags.INHERIT, 0))
            {
                throw new Win32Exception("STDERR pipe handle setup failed");
            }

            if (!CreatePipe(out stdin_read, out stdin_write, pipesec, 0))
            {
                throw new Win32Exception("STDIN pipe setup failed");
            }
            if (!SetHandleInformation(stdin_write, HandleFlags.INHERIT, 0))
            {
                throw new Win32Exception("STDIN pipe handle setup failed");
            }

            si.startupInfo.hStdOutput = stdout_write;
            si.startupInfo.hStdError  = stderr_write;
            si.startupInfo.hStdInput  = stdin_read;

            // Setup the stdin buffer
            UTF8Encoding utf8_encoding = new UTF8Encoding(false);
            FileStream   stdin_fs      = new FileStream(stdin_write, FileAccess.Write, 32768);
            StreamWriter stdin         = new StreamWriter(stdin_fs, utf8_encoding, 32768);

            // Create the environment block if set
            IntPtr lpEnvironment = IntPtr.Zero;

            CreationFlags startup_flags = CreationFlags.CREATE_UNICODE_ENVIRONMENT;

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

            // Get the user tokens to try running processes with
            List <IntPtr> tokens = GetUserTokens(account, username, password, logonType);

            bool launch_success = false;

            foreach (IntPtr token in tokens)
            {
                if (CreateProcessWithTokenW(
                        token,
                        logonFlags,
                        null,
                        new StringBuilder(lpCommandLine),
                        startup_flags,
                        lpEnvironment,
                        lpCurrentDirectory,
                        si,
                        out pi))
                {
                    launch_success = true;
                    break;
                }
            }

            if (!launch_success)
            {
                throw new Win32Exception("Failed to start become process");
            }

            CommandResult result = new CommandResult();
            // Setup the output buffers and get stdout/stderr
            FileStream   stdout_fs = new FileStream(stdout_read, FileAccess.Read, 4096);
            StreamReader stdout    = new StreamReader(stdout_fs, utf8_encoding, true, 4096);

            stdout_write.Close();

            FileStream   stderr_fs = new FileStream(stderr_read, FileAccess.Read, 4096);
            StreamReader stderr    = new StreamReader(stderr_fs, utf8_encoding, true, 4096);

            stderr_write.Close();

            stdin.WriteLine(stdinInput);
            stdin.Close();

            string stdout_str, stderr_str = null;

            GetProcessOutput(stdout, stderr, out stdout_str, out stderr_str);
            UInt32 rc = GetProcessExitCode(pi.hProcess);

            result.StandardOut   = stdout_str;
            result.StandardError = stderr_str;
            result.ExitCode      = rc;

            return(result);
        }