C# 中检测控制台/命令行是否正在等待用户输入

问题描述 投票:0回答:1

我正在使用 WPF 和 C# 为我的语言 EasyBite 创建 IDE,我向 IDE 添加了一个输出面板,以使用 Process 类显示所联系的命令提示符的输出,一切正常,直到程序有输入。一旦到达输入,它将终止执行。如果我直接使用命令提示符运行程序而不使用 IDE,一切都可以。

请问,如何像其他 IDE 那样根据 IDE 的运行来检测命令提示符是否正在等待输入。

逻辑是:我使用 Process 将 EasyBite 解释器和文件名作为参数传递,代码如下:

private void StartEasyBiteProcess(string filePath, string compilerPath)
        {
            Dispatcher.Invoke(() =>
            {
                
                OutputTextBox.AppendText("EasyBite Executing...\n\n");

                
                OutputTextBox.Foreground = new SolidColorBrush(Colors.Green);
            });
            _easyBiteProcess = new Process();
            _easyBiteProcess.StartInfo.FileName = Path.Combine(compilerPath, "EasyBite.exe") ; 
            _easyBiteProcess.StartInfo.Arguments = filePath; // Pass the file path as a command-line argument
            _easyBiteProcess.StartInfo.UseShellExecute = false;
            _easyBiteProcess.StartInfo.RedirectStandardInput = true;
            _easyBiteProcess.StartInfo.RedirectStandardOutput = true;
            _easyBiteProcess.StartInfo.CreateNoWindow = true;
            _easyBiteProcess.OutputDataReceived += EasyBiteProcess_OutputDataReceived;
            _easyBiteProcess.EnableRaisingEvents = true;
            _easyBiteProcess.Exited += EasyBiteProcess_Exited;
            _easyBiteProcess.Start();

            _easyBiteProcess.BeginOutputReadLine();
            foreach(ProcessThread thread in process.Threads)
    if (thread.ThreadState == ThreadState.Wait
        && thread.WaitReason == ThreadWaitReason.UserRequest)
              _waitForInput = true;

        }
        private void EasyBiteProcess_Exited(object sender, EventArgs e)
        {
            Dispatcher.Invoke(() =>
            {
                OutputTextBox.Text += "EasyBite program exited.\n";
                OutputTextBox.Foreground = new SolidColorBrush(Colors.White);
            });
        }
        private void EasyBiteProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {

            Dispatcher.Invoke(() =>
            {
                if (_waitForInput)
                {
                    OutputTextBox.IsReadOnly = false;
                    // Handle user input
                    HandleProgramInput(e.Data);
                    _waitForInput = false;  // Assuming that the input handling is synchronous and only for one line
                }
                else
                {
                    Console.Read();
                    // Handle program output
                    OutputTextBox.AppendText("> " + e.Data + "\n");
                    OutputTextBox.Foreground = new SolidColorBrush(Colors.White);
                    OutputTextBox.CaretIndex = OutputTextBox.Text.Length;
                    OutputTextBox.ScrollToEnd(); // Scrolls to the end of the TextBox
                }
            });
        }

        private void HandleProgramInput(string userInput)
        {
            // Write user input to the standard input stream of EasyBite.exe
            using (StreamWriter streamWriter = _easyBiteProcess.StandardInput)
            {
                if (streamWriter.BaseStream.CanWrite)
                {
                    streamWriter.WriteLine(userInput);
                }
            }

            OutputTextBox.AppendText("> " + userInput + "\n");
            OutputTextBox.CaretIndex = OutputTextBox.Text.Length;
            OutputTextBox.ScrollToEnd();
            // Scrolls to the end of the TextBox
        }

我在 Stackoverflow 上找到了这个,但不起作用

foreach(ProcessThread thread in process.Threads)
    if (thread.ThreadState == ThreadState.Wait
        && thread.WaitReason == ThreadWaitReason.UserRequest)

如果有人可以提供帮助,我将不胜感激。谢谢你。

c# wpf input process command-line-interface
1个回答
0
投票

Console.KeyAvailable
属性用于检查密钥是否可用于读取而不阻止程序的执行。这可用于检测控制台/命令行是否正在等待用户输入。

参考工作示例:

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Press any key to continue or 'Q' to quit.");

        
        while (!Console.KeyAvailable) // Check if a key is available without blocking the program
        {
            // Your main program logic goes here
            

            Console.WriteLine("Working...");
            System.Threading.Thread.Sleep(1000); // Simulating some work
        }

        
        ConsoleKeyInfo key = Console.ReadKey(); // If a key is pressed, read the key

        
        if (key.Key == ConsoleKey.Q) // Check if the pressed key is 'Q' or 'q' to quit
        {
            Console.WriteLine("\nQuitting...");
        }
        else
        {
            Console.WriteLine("\nContinuing...");
        }

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.