/// <summary> /// 启动进程 /// </summary> /// <param name="flags">创建状态标识</param> /// <returns>是否成功</returns> public bool Start(TmphCreateFlags 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(GetType().Name); } var lpStartupInfo = new TmphStartupInfo(); var lpProcessInformation = new TmphProcessInformation(); var processHandle = assembly.CreateInstance(safeProcessHandleFullName, false, BindingFlags.Instance | BindingFlags.NonPublic, null, null, null, null); threadHandle = new TmphSafeThreadHandle(); var error = 0; SafeFileHandle parentHandle = null; SafeFileHandle outputParentHandle = null; SafeFileHandle errorParentHandle = null; var gcHandle = new GCHandle(); try { bool flag; if ((StartInfo.RedirectStandardInput || StartInfo.RedirectStandardOutput) || StartInfo.RedirectStandardError) { if (StartInfo.RedirectStandardInput) { createPipe(out parentHandle, out lpStartupInfo.StandardInput, true); } else { lpStartupInfo.StandardInput = new SafeFileHandle(TmphKernel32.GetStdHandle(TmphKernel32.TmphStandardHandle.StandardInput), false); } if (StartInfo.RedirectStandardOutput) { createPipe(out outputParentHandle, out lpStartupInfo.StandardOutput, false); } else { lpStartupInfo.StandardOutput = new SafeFileHandle(TmphKernel32.GetStdHandle(TmphKernel32.TmphStandardHandle.StandardOutput), false); } if (StartInfo.RedirectStandardError) { createPipe(out errorParentHandle, out lpStartupInfo.StandardError, false); } else { lpStartupInfo.StandardError = new SafeFileHandle(TmphKernel32.GetStdHandle(TmphKernel32.TmphStandardHandle.StandardError), false); } lpStartupInfo.Flags = TmphStartupInfoFlags.STARTF_USESTDHANDLES; } if (StartInfo.CreateNoWindow) { creationFlags |= TmphCreateFlags.CREATE_NO_WINDOW; } var zero = IntPtr.Zero; var environmentVariables = startInfoEnvironmentVariables(StartInfo); if (environmentVariables != null) { var unicode = false; if (processManagerIsNt()) { creationFlags |= TmphCreateFlags.CREATE_UNICODE_ENVIRONMENT; unicode = true; } gcHandle = GCHandle.Alloc(environmentBlockToByteArray(environmentVariables, unicode), GCHandleType.Pinned); zero = gcHandle.AddrOfPinnedObject(); } var workingDirectory = StartInfo.WorkingDirectory; if (workingDirectory == string.Empty) { workingDirectory = Environment.CurrentDirectory; } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { flag = TmphKernel32.CreateProcess(null, commandLine, null, null, true, creationFlags, zero, workingDirectory, lpStartupInfo, lpProcessInformation); if (!flag) { error = Marshal.GetLastWin32Error(); } if ((lpProcessInformation.Process != IntPtr.Zero) && (lpProcessInformation.Process != TmphKernel32.INVALID_HANDLE_VALUE)) { processInitialSetHandle(processHandle, lpProcessInformation.Process); } if ((lpProcessInformation.Thread != IntPtr.Zero) && (lpProcessInformation.Thread != TmphKernel32.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) { var input = new StreamWriter(new FileStream(parentHandle, FileAccess.Write, 0x1000, false), Encoding.GetEncoding(TmphKernel32.GetConsoleCP()), 0x1000); input.AutoFlush = true; standardInput(this, input); } if (StartInfo.RedirectStandardOutput) { var encoding1 = (StartInfo.StandardOutputEncoding != null) ? StartInfo.StandardOutputEncoding : Encoding.GetEncoding(TmphKernel32.GetConsoleOutputCP()); standardOutput(this, new StreamReader(new FileStream(outputParentHandle, FileAccess.Read, 0x1000, false), encoding1, true, 0x1000)); } if (StartInfo.RedirectStandardError) { var encoding2 = (StartInfo.StandardErrorEncoding != null) ? StartInfo.StandardErrorEncoding : Encoding.GetEncoding(TmphKernel32.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 & TmphCreateFlags.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); } }