WPF服务器启动器切换视图后丢失CMD进程连接问题求助
问题:WPF服务器启动器切换视图后丢失CMD进程交互连接
基于.NET Framework开发WPF服务器启动器,用于替代手动调整文件的操作。当前已实现通过GUI与服务器批处理文件交互,但切换视图(如进入设置、日志页面等)时,会丢失与运行中CMD进程的连接,输入输出停止工作,尽管服务器进程仍在运行。
关键组件说明
tb:用于命令输入的TextBoxlb:显示服务器状态的LabelCurrentServer:代表各控件中选中的服务器实例
已尝试方案
- 使用类似逻辑切换到PowerShell
- 在独立线程中运行进程
- 不依赖批处理文件,直接通过代码参数启动进程
- 在主窗口中存储命令处理器实例
- 所有UI操作通过
Dispatcher.Invoke执行 - 借助AI工具寻求解决方案
相关代码
private Process cmdProcess; private bool isServerOnline = false; public void ComandPromptRun() { MainWindow mainWindow = (MainWindow)Application.Current.MainWindow; // Check if the process for the current server already exists if (mainWindow.MinecraftJavaCmdProcesses.ContainsKey(mainWindow.CurrentServer) && mainWindow.MinecraftJavaCmdProcesses[mainWindow.CurrentServer] != null) { cmdProcess = mainWindow.MinecraftJavaCmdProcesses[mainWindow.CurrentServer]; if (cmdProcess != null && !cmdProcess.HasExited) { // Reattach output event handler cmdProcess.OutputDataReceived -= CmdProcess_OutputDataReceived; cmdProcess.OutputDataReceived += CmdProcess_OutputDataReceived; // Ensure the process is still reading output if (cmdProcess.StandardOutput.BaseStream.CanRead) { cmdProcess.BeginOutputReadLine(); // Reattach reading } else { MessageBox.Show("The output stream is unavailable. Please restart the process."); } // Load previous logs if any foreach (var log in mainWindow.MinecraftJavaLogs[mainWindow.CurrentServer]) { Dispatcher.Invoke(() => { TB_ComandPromptOutput.AppendText(log + Environment.NewLine); }); } return; // Avoid starting a new process } else { MessageBox.Show("Process has exited or is unavailable. You will need to restart the server."); mainWindow.MinecraftJavaCmdProcesses[mainWindow.CurrentServer] = null; } } // Start a new process if it doesn't exist StartNewMinecraftProcess(mainWindow); } private void StartNewMinecraftProcess(MainWindow mainWindow) { string selectedServerPath = mainWindow.MinecraftJavaServers[mainWindow.CurrentServer]; // Start a new thread to run the server process new Thread(() => { try { MessageBox.Show($"Starting server at: {selectedServerPath}"); Thread.CurrentThread.IsBackground = true; cmdProcess = new Process { StartInfo = new ProcessStartInfo { FileName = $@"{selectedServerPath}\Run.bat", WorkingDirectory = selectedServerPath, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardInput = true, CreateNoWindow = true } }; cmdProcess.OutputDataReceived += CmdProcess_OutputDataReceived; cmdProcess.Start(); cmdProcess.BeginOutputReadLine(); // Store the new process in the dictionary mainWindow.MinecraftJavaCmdProcesses[mainWindow.CurrentServer] = cmdProcess; } catch (Exception ex) { Dispatcher.Invoke(() => MessageBox.Show($"Failed to start server: {ex.Message}")); } }).Start(); } private void CmdProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) { if (!string.IsNullOrEmpty(e.Data)) { Dispatcher.Invoke(() => { // Append to TextBox TB_ComandPromptOutput.AppendText(e.Data + Environment.NewLine); // Store log in the MainWindow dictionary MainWindow mainWindow = (MainWindow)Application.Current.MainWindow; if (!mainWindow.MinecraftJavaLogs.ContainsKey(mainWindow.CurrentServer)) { mainWindow.MinecraftJavaLogs[mainWindow.CurrentServer] = new List<string>(); } mainWindow.MinecraftJavaLogs[mainWindow.CurrentServer].Add(e.Data); }); } } public void CmdProcess_IncomeDataSent(string inputData) { if (!string.IsNullOrEmpty(inputData)) { Dispatcher.Invoke(() => { if (cmdProcess != null && !cmdProcess.HasExited) { if (cmdProcess.StandardInput != null && !cmdProcess.StandardInput.BaseStream.CanWrite) { MessageBox.Show("The input stream is closed or unavailable."); return; } cmdProcess.StandardInput.WriteLine(inputData); cmdProcess.StandardInput.Flush(); } else { MessageBox.Show("Command prompt process is not running or has exited."); } }); } } private void TB_ComandPromptInput_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { CmdProcess_IncomeDataSent(TB_ComandPromptInput.Text); if (TB_ComandPromptInput.Text.ToLower() == "stop") { lb_IsServerOnline.Content = "Offline"; lb_IsServerOnline.Foreground = new SolidColorBrush(Colors.Red); TB_ComandPromptInput.IsEnabled = false; isServerOnline = false; } TB_ComandPromptInput.Text = string.Empty; } }
内容的提问来源于stack exchange,提问作者Damien Davey
相关产品推荐
相关产品推荐

