正如标题所说,我有一个使用暂停的批处理文件。这是我将用来解释问题的示例批处理文件:
@echo off
pause
echo DONE
pause
从资源管理器运行批处理文件时,它显示以下内容:
"Press any key to continue..."
然后当用户按下一个键时,将显示以下内容:
Press any key to continue...
DONE
Press any key to continue...
我遇到的问题是,当从我的 Windows 窗体应用程序运行这个 .bat 文件时,输出不会显示“按任意键继续...”,直到用户按下一个键。这是一个问题,因为用户需要知道他们需要在按下某个键之前按下它。这是显示该问题的视频。
当批处理文件执行时,左侧的圆圈变为灰色。然后鼠标移动到文本框,我按下键盘上的一个键。然后输出文本框显示文本。
所以我正在试验,我在 .bat 文件中添加了一行:
@echo off
echo Why is this line showing but the other line doesn't until i press a key?
pause
echo DONE
pause
这是结果。
所以这里是代码:
void StartNewProcess(string batchFile)
{
//Focuses the input textbox
Input_TextBox.Focus();
//Set up process
ProcessStartInfo processStartInfo = new ProcessStartInfo(batchFile);
processStartInfo.WorkingDirectory = appDir;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.CreateNoWindow = true;
process = new Process();
process.EnableRaisingEvents = true;
process.StartInfo = processStartInfo;
//Start process
process.Start();
process.BeginOutputReadLine();
//This is the input textbox
stdin = process.StandardInput;
process.OutputDataReceived += (s, evt) =>
{
if (evt.Data != null)
{
BeginInvoke(new MethodInvoker(() => {
newOutputLine = evt.Data; //Reference to current incoming line of text
Output_TextBox.AppendText(newOutputLine + Environment.NewLine);
Output_TextBox.ScrollToCaret();
if (evt.Data == "DONE")
{
MessageBox.Show("Task completed successfully!", "Notification");
Output_TextBox.Text = ""; //Clear the output textbox
}
}));
}
};
process.Exited += (s, evt) => {
process.Close();
if (process != null)
{
process.Dispose();
}
};
}
private void Input_Panel_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
stdin.WriteLine(Input_TextBox.Text);
}
}
我到底需要做什么才能在按下键之前显示“按任意键继续...”?
这不是我遇到的这个问题的唯一例子。例如,如果批处理文件需要输入一个值作为对选择的响应,则在输入答案之前不会显示问题......例如“输入您的姓名:”直到用户输入后才会显示输入名称并按回车键,此时将显示“输入您的姓名:样品名称”。这对用户没有帮助,因为他们需要知道在输入之前需要输入名称。
我有许多批处理文件,其中显示了很多选择,并且用户需要知道这些选择是什么才能使我的应用程序正常工作。所以这个功能就像主要的部分。xD
有任何想法吗?
谢谢
编辑 所以感谢@MatthewMiller 为我提供了解决方案。所以这里适用于其他所有人:
void StartNewProcess(string batchFile)
{
//Set up process
ProcessStartInfo processStartInfo = new ProcessStartInfo(batchFile);
processStartInfo.WorkingDirectory = appDir;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.CreateNoWindow = true;
process = new Process();
process.EnableRaisingEvents = true;
process.StartInfo = processStartInfo;
//Start process
process.Start();
//process.BeginOutputReadLine();
//This is the input textbox
stdin = process.StandardInput;
// Get the output stream from the new process.
StreamReader stdout = process.StandardOutput;
// Define a buffer we will use to store characters read.
const int BUFFER_SIZE = 1;
char[] buffer = new char[BUFFER_SIZE];
// The following specifies reading from the output stream to a buffer
// and then appending the result to the form.
Task<int> readTask = stdout.ReadAsync(buffer, 0, BUFFER_SIZE);
Action<Task<int>> appendAction = null;
appendAction = (read) => {
string bufferString = new string(buffer);
// `read.Result` represents the number of characters read.
string newText = bufferString.Substring(0, read.Result);
// *Append new text to form here.* NOTE: New text might not be a complete line.
SetText(newText); //Have to set text this way due to other thread
// If we read in an entire buffer of text, we need to keep reading.
// Otherwise, stop reading and finish up.
if (read.Result == BUFFER_SIZE)
{
readTask = stdout.ReadAsync(buffer, 0, BUFFER_SIZE);
readTask.ContinueWith(appendAction);
}
else
{
// *Handle process has ended here.*
}
};
readTask.ContinueWith(appendAction);
}
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.Output_TextBox.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
Output_TextBox.AppendText(text);
}
}
非常感谢!