Esempio n. 1
0
        /// <summary>
        /// Creates a process based on the CreateProcess API call.
        /// </summary>
        /// <param name="lpApplicationName">The name of the executable or batch file to execute</param>
        /// <param name="lpCommandLine">The command line to execute, typically this includes lpApplication as the first argument</param>
        /// <param name="lpCurrentDirectory">The full path to the current directory for the process, null will have the same cwd as the calling process</param>
        /// <param name="environment">A dictionary of key/value pairs to define the new process environment</param>
        /// <param name="stdin">A byte array to send over the stdin pipe</param>
        /// <returns>Result object that contains the command output and return code</returns>
        public static Result CreateProcess(string lpApplicationName, string lpCommandLine, string lpCurrentDirectory,
                                           IDictionary environment, byte[] stdin)
        {
            NativeHelpers.ProcessCreationFlags creationFlags = NativeHelpers.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT |
                                                               NativeHelpers.ProcessCreationFlags.EXTENDED_STARTUPINFO_PRESENT;
            NativeHelpers.PROCESS_INFORMATION pi = new NativeHelpers.PROCESS_INFORMATION();
            NativeHelpers.STARTUPINFOEX       si = new NativeHelpers.STARTUPINFOEX();
            si.startupInfo.dwFlags = NativeHelpers.StartupInfoFlags.USESTDHANDLES;

            SafeFileHandle stdoutRead, stdoutWrite, stderrRead, stderrWrite, stdinRead, stdinWrite;

            CreateStdioPipes(si, out stdoutRead, out stdoutWrite, out stderrRead, out stderrWrite, out stdinRead,
                             out stdinWrite);
            FileStream stdinStream = new FileStream(stdinWrite, FileAccess.Write);

            // $null from PowerShell ends up as an empty string, we need to convert back as an empty string doesn't
            // make sense for these parameters
            if (lpApplicationName == "")
            {
                lpApplicationName = null;
            }

            if (lpCurrentDirectory == "")
            {
                lpCurrentDirectory = null;
            }

            using (SafeMemoryBuffer lpEnvironment = CreateEnvironmentPointer(environment))
            {
                // Create console with utf-8 CP if no existing console is present
                bool isConsole = false;
                if (NativeMethods.GetConsoleWindow() == IntPtr.Zero)
                {
                    isConsole = NativeMethods.AllocConsole();

                    // Set console input/output codepage to UTF-8
                    NativeMethods.SetConsoleCP(65001);
                    NativeMethods.SetConsoleOutputCP(65001);
                }

                try
                {
                    StringBuilder commandLine = new StringBuilder(lpCommandLine);
                    if (!NativeMethods.CreateProcessW(lpApplicationName, commandLine, IntPtr.Zero, IntPtr.Zero,
                                                      true, creationFlags, lpEnvironment, lpCurrentDirectory, si, out pi))
                    {
                        throw new Win32Exception("CreateProcessW() failed");
                    }
                }
                finally
                {
                    if (isConsole)
                    {
                        NativeMethods.FreeConsole();
                    }
                }
            }

            return(WaitProcess(stdoutRead, stdoutWrite, stderrRead, stderrWrite, stdinStream, stdin, pi.hProcess));
        }
Esempio n. 2
0
 public static extern bool CreateProcessW(
     [MarshalAs(UnmanagedType.LPWStr)] string lpApplicationName,
     StringBuilder lpCommandLine,
     IntPtr lpProcessAttributes,
     IntPtr lpThreadAttributes,
     bool bInheritHandles,
     NativeHelpers.ProcessCreationFlags dwCreationFlags,
     SafeMemoryBuffer lpEnvironment,
     [MarshalAs(UnmanagedType.LPWStr)] string lpCurrentDirectory,
     NativeHelpers.STARTUPINFOEX lpStartupInfo,
     out NativeHelpers.PROCESS_INFORMATION lpProcessInformation);
Esempio n. 3
0
        /// <summary>
        /// Parses a command line string into an argv array according to the Windows rules
        /// </summary>
        /// <param name="lpCommandLine">The command line to parse</param>
        /// <returns>An array of arguments interpreted by Windows</returns>
        public static string[] ParseCommandLine(string lpCommandLine)
        {
            int numArgs;

            using (SafeMemoryBuffer buf = NativeMethods.CommandLineToArgvW(lpCommandLine, out numArgs))
            {
                if (buf.IsInvalid)
                {
                    throw new Win32Exception("Error parsing command line");
                }
                IntPtr[] strptrs = new IntPtr[numArgs];
                Marshal.Copy(buf.DangerousGetHandle(), strptrs, 0, numArgs);
                return(strptrs.Select(s => Marshal.PtrToStringUni(s)).ToArray());
            }
        }