/// <summary> /// 启动进程 /// </summary> /// <param name="flags">创建状态标识</param> /// <returns>是否成功</returns> public bool Start(createFlags creationFlags) { Close(); if ((StartInfo.StandardOutputEncoding != null) && !StartInfo.RedirectStandardOutput) { throw new InvalidOperationException("StandardOutputEncodingNotAllowed"); } if ((StartInfo.StandardErrorEncoding != null) && !StartInfo.RedirectStandardError) { throw new InvalidOperationException("StandardErrorEncodingNotAllowed"); } if (disposed(this)) { throw new ObjectDisposedException(base.GetType().Name); } startupInfo lpStartupInfo = new startupInfo(); processInformation lpProcessInformation = new processInformation(); object processHandle = assembly.CreateInstance(safeProcessHandleFullName, false, BindingFlags.Instance | BindingFlags.NonPublic, null, null, null, null); threadHandle = new safeThreadHandle(); int error = 0; SafeFileHandle parentHandle = null; SafeFileHandle outputParentHandle = null; SafeFileHandle errorParentHandle = null; GCHandle gcHandle = new GCHandle(); try { bool flag; if ((StartInfo.RedirectStandardInput || StartInfo.RedirectStandardOutput) || StartInfo.RedirectStandardError) { if (StartInfo.RedirectStandardInput) { this.createPipe(out parentHandle, out lpStartupInfo.StandardInput, true); } else { lpStartupInfo.StandardInput = new SafeFileHandle(kernel32.GetStdHandle(kernel32.standardHandle.StandardInput), false); } if (StartInfo.RedirectStandardOutput) { this.createPipe(out outputParentHandle, out lpStartupInfo.StandardOutput, false); } else { lpStartupInfo.StandardOutput = new SafeFileHandle(kernel32.GetStdHandle(kernel32.standardHandle.StandardOutput), false); } if (StartInfo.RedirectStandardError) { this.createPipe(out errorParentHandle, out lpStartupInfo.StandardError, false); } else { lpStartupInfo.StandardError = new SafeFileHandle(kernel32.GetStdHandle(kernel32.standardHandle.StandardError), false); } lpStartupInfo.Flags = startupInfoFlags.STARTF_USESTDHANDLES; } if (StartInfo.CreateNoWindow) { creationFlags |= createFlags.CREATE_NO_WINDOW; } IntPtr zero = IntPtr.Zero; StringDictionary environmentVariables = startInfoEnvironmentVariables(StartInfo); if (environmentVariables != null) { bool unicode = false; if (processManagerIsNt()) { creationFlags |= createFlags.CREATE_UNICODE_ENVIRONMENT; unicode = true; } gcHandle = GCHandle.Alloc(environmentBlockToByteArray(environmentVariables, unicode), GCHandleType.Pinned); zero = gcHandle.AddrOfPinnedObject(); } string workingDirectory = StartInfo.WorkingDirectory; if (workingDirectory == string.Empty) { workingDirectory = Environment.CurrentDirectory; } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { flag = kernel32.CreateProcess(null, commandLine, null, null, true, creationFlags, zero, workingDirectory, lpStartupInfo, lpProcessInformation); if (!flag) { error = Marshal.GetLastWin32Error(); } if ((lpProcessInformation.Process != IntPtr.Zero) && (lpProcessInformation.Process != kernel32.INVALID_HANDLE_VALUE)) { processInitialSetHandle(processHandle, lpProcessInformation.Process); } if ((lpProcessInformation.Thread != IntPtr.Zero) && (lpProcessInformation.Thread != kernel32.INVALID_HANDLE_VALUE)) { threadHandle.InitialSetHandle(lpProcessInformation.Thread); } } if (!flag) { if (error == 0xc1) { throw new Win32Exception(error, "InvalidApplication"); } throw new Win32Exception(error); } } finally { if (gcHandle.IsAllocated) { gcHandle.Free(); } lpStartupInfo.Dispose(); } if (StartInfo.RedirectStandardInput) { StreamWriter input = new StreamWriter(new FileStream(parentHandle, FileAccess.Write, 0x1000, false), Encoding.GetEncoding(kernel32.GetConsoleCP()), 0x1000); input.AutoFlush = true; standardInput(this, input); } if (StartInfo.RedirectStandardOutput) { Encoding encoding1 = (StartInfo.StandardOutputEncoding != null) ? StartInfo.StandardOutputEncoding : Encoding.GetEncoding(kernel32.GetConsoleOutputCP()); standardOutput(this, new StreamReader(new FileStream(outputParentHandle, FileAccess.Read, 0x1000, false), encoding1, true, 0x1000)); } if (StartInfo.RedirectStandardError) { Encoding encoding2 = (StartInfo.StandardErrorEncoding != null) ? StartInfo.StandardErrorEncoding : Encoding.GetEncoding(kernel32.GetConsoleOutputCP()); standardError(this, new StreamReader(new FileStream(errorParentHandle, FileAccess.Read, 0x1000, false), encoding2, true, 0x1000)); } if (!handleIsInvalid(processHandle)) { setProcessHandle(this, processHandle); setProcessId(this, lpProcessInformation.ProcessId); if ((creationFlags & createFlags.CREATE_SUSPENDED) == 0) threadHandle.Close(); return true; } return false; }
/// <summary> /// 释放资源 /// </summary> /// <param name="disposing">是否释放资源</param> protected override void Dispose(bool disposing) { if (!disposed(this)) { if (threadHandle != null) { threadHandle.Dispose(); threadHandle = null; } base.Dispose(disposing); } }