///<summary> /// 执行外部程序 /// </summary> /// <param name="filePath">程序路径</param> /// <param name="arguments">参数</param> public void RunExe(string filePath, string arguments) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException(nameof(filePath), "外部程序路径为空"); } if (!File.Exists(filePath)) { throw new FileNotFoundException($"文件 [{filePath}] 不存在", filePath); } try { _process.StartInfo.FileName = filePath; _process.StartInfo.Arguments = arguments; _process.StartInfo.WorkingDirectory = Path.GetDirectoryName(filePath); _process.StartInfo.ErrorDialog = false; _process.StartInfo.UseShellExecute = false; _process.StartInfo.CreateNoWindow = true; _process.EnableRaisingEvents = true; _process.StartInfo.RedirectStandardOutput = true; _process.StartInfo.RedirectStandardInput = true; _process.StartInfo.RedirectStandardError = true; _process.StartInfo.StandardOutputEncoding = Encoding.UTF8; _process.StartInfo.StandardErrorEncoding = Encoding.UTF8; _process.Exited += (s, e) => ProcessExitedHandler?.Invoke(this, "进程已退出"); _process.OutputDataReceived += ProcessOnOutputDataReceived; _process.ErrorDataReceived += ProcessOnErrorDataReceived; _process.Start(); _process.BeginErrorReadLine(); _process.BeginOutputReadLine(); } catch (Exception ex) { throw ex; } }
private void ButtonRender_Click(object sender, EventArgs e) { switch (_status) { case ProcessingStatus.RENDERING: PromptCancelConfirmation(); break; default: if (Directory.Exists(textBoxWorld.Text.ToString()) && Directory.Exists(textBoxOutput.Text.ToString())) { formConfigure.ApplySettings(); formConfigure.Hide(); switch (comboBoxVersion.SelectedIndex) { // .cs case 0: UHandler = UpdateConsole; ProcessExitHandler = ProcessExited; Thread renderThread = new Thread(new ThreadStart(() => { _renderProcess = new Process(); _renderProcess.StartInfo.FileName = Settings.config_cs["executable"]; _renderProcess.StartInfo.Arguments = Settings.GetArguments(PapyrusVariant.PAPYRUSCS, false, Path.GetFullPath(textBoxWorld.Text.ToString()), Path.GetFullPath(textBoxOutput.Text.ToString())); _renderProcess.StartInfo.UseShellExecute = false; _renderProcess.StartInfo.RedirectStandardOutput = true; _renderProcess.StartInfo.CreateNoWindow = true; _renderProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; _renderProcess.StartInfo.RedirectStandardError = true; _renderProcess.ErrorDataReceived += (object errorSender, DataReceivedEventArgs errorEventArgs) => { MessageBox.Show(String.Format("An error occured while rendering your world!\n{0}", errorEventArgs.Data), "An error occurred", MessageBoxButtons.OK, MessageBoxIcon.Error); }; _renderProcess.OutputDataReceived += (object threadSender, DataReceivedEventArgs eArgs) => { this.UHandler?.Invoke(eArgs.Data); }; _renderProcess.Start(); _renderProcess.BeginOutputReadLine(); _renderProcess.WaitForExit(); ProcessExitHandler?.Invoke(_renderProcess.ExitCode); _renderProcess.Close(); })); renderThread.Start(); break; // .js case 1: // Not available break; } _logContent.Clear(); _status = ProcessingStatus.RENDERING; } else { MessageBox.Show("World and/ or output directory is invalid or does not exist.", "Invalid directory", MessageBoxButtons.OK, MessageBoxIcon.Warning); } break; } }
private static void MonitorProcess(string filename, VisibleWindowHandler visibleWindowHandler, ProcessExitedHandler processExitHandler) { //Get the active window since the window activation will be lost by lauching the display properties IntPtr activehWnd = IntPtr.Zero; ManualResetEvent waitEvent = new ManualResetEvent(false); ProcessMonitor processMonitor = new ProcessMonitor(); Process themeChangeProcess = new Process(); themeChangeProcess.StartInfo.FileName = filename; try { //Initialize the wait event waitEvent.Reset(); activehWnd = User32.GetForegroundWindow(); //This field is set when the correct process is started and checked when any process exits int processId = 0; processMonitor.VisibleWindowFound += new VisibleWindowHandler(delegate(IntPtr topLevelhWnd, IntPtr hWnd, Process process, string title) { if (process.ProcessName.ToLowerInvariant().Equals(ThemeProcessName)) { processId = process.Id; User32.SetForegroundWindow(topLevelhWnd); //In case the dialog was opened previously Thread.Sleep(2000); if (visibleWindowHandler != null) { visibleWindowHandler(topLevelhWnd, hWnd, process, title); } } }); processMonitor.ProcessExited += new ProcessExitedHandler(delegate(Process process) { if (process.Id == processId) { if (processExitHandler != null) { processExitHandler(process); } Thread.Sleep(1000); //For good measure waitEvent.Set(); } }); themeChangeProcess.Start(); //Start monitoring processes processMonitor.AddProcess(ThemeProcessName); processMonitor.Start(); waitEvent.WaitOne(60000, false); } finally { if (processMonitor != null) { processMonitor.Stop(); } //Restore the active window if (activehWnd != IntPtr.Zero) { User32.SetForegroundWindow(activehWnd); } } }