C# 如何确定cmd.exe何时完成
我找到了一些代码。它捕获cmd.exe的输出并向其发送输入。我在我们的应用程序中的表单上使用它(经过大量修改)。它运行良好,因此我们可以对用户隐藏cmd.exe,但允许管理员使用此表单。其他好处包括收藏列表等 下面是一些代码。注意:我删除了70%的代码以简化它,因此可能会出现问题。如果有人希望运行此代码,并且他们有问题,请让我知道,我将编辑它并确保它工作正常。它所需要的只是一个带有两个文本框的表单,txtConsoleIn和txtConsoleOut加上一个计时器;tmrSelectedCommandC# 如何确定cmd.exe何时完成,c#,windows,cmd,C#,Windows,Cmd,我找到了一些代码。它捕获cmd.exe的输出并向其发送输入。我在我们的应用程序中的表单上使用它(经过大量修改)。它运行良好,因此我们可以对用户隐藏cmd.exe,但允许管理员使用此表单。其他好处包括收藏列表等 下面是一些代码。注意:我删除了70%的代码以简化它,因此可能会出现问题。如果有人希望运行此代码,并且他们有问题,请让我知道,我将编辑它并确保它工作正常。它所需要的只是一个带有两个文本框的表单,txtConsoleIn和txtConsoleOut加上一个计时器;tmrSelectedComm
public partial class frmCommandPrompt : Form
{
private bool CancelOutput;
private bool FirstTime = true;
private bool InternalCommand;
private string InternalCommandResponse;
private ProcessStartInfo psi;
private Process p;
private string SelectedCommand;
private bool SelectedCommandExecuteNow;
private delegate void InvokeWithString(string text);
public frmCommandPrompt()
{
InitializeComponent();
}
private void frmCommandPrompt_Shown(object sender, EventArgs e)
{
this.txtConsoleIn.Select();
}
private void tmrSelectedCommand_Tick(object sender, EventArgs e)
{
tmrSelectedCommand.Enabled = false;
if (SelectedCommand != string.Empty)
{
if (SelectedCommandExecuteNow)
{
ExecuteCommand(SelectedCommand);
}
else
{
txtConsoleIn.Text = SelectedCommand;
txtConsoleIn.SelectionStart = txtConsoleIn.Text.Length;
txtConsoleIn.Select();
}
SelectedCommand = string.Empty;
SelectedCommandExecuteNow = false;
}
}
// Sending console commands
private void txtConsoleIn_KeyUp(object sender, KeyEventArgs e)
{
string Command;
if ((int)e.KeyCode == (int)Keys.Return)
{
InternalCommand = false;
Command = txtConsoleIn.Text;
ExecuteCommand(Command);
txtConsoleIn.Clear();
}
}
private void Async_Data_Received(Object sender, DataReceivedEventArgs e)
{
if (this.IsHandleCreated)
{
this.Invoke(new InvokeWithString(Sync_Output), e.Data);
}
}
private void Sync_Output(string text)
{
if (!InternalCommand)
{
if (!CancelOutput)
{
OutputText(text);
}
}
else
{
if (text != String.Empty)
{
InternalCommandResponse = text;
InternalCommand = false;
}
}
}
private void ExecuteRecentCommand(string Command, bool ExecuteNow)
{
SelectedCommand = Command;
SelectedCommandExecuteNow = ExecuteNow;
tmrSelectedCommand.Enabled = true;
}
private void ExecuteCommand(string Command)
{
CancelOutput = false;
p.StandardInput.WriteLine(Command);
}
private void OutputText(string text)
{
txtConsoleOut.AppendText(text + Environment.NewLine);
txtConsoleOut.ScrollToCaret();
}
}
我想显示路径,比如prompt=$p$G。我可以发出命令echo%cd%并捕获输出,同时抑制该命令和输出。我
然后可以输出这个并添加一个“>”,到目前为止还不错。现在问题来了
有时命令可以更改路径。所以我需要再次检查路径,但是什么时候?如果有人输入长时间运行的命令怎么办?我怎么知道什么时候完成?为了便于使用,我更愿意使它尽可能接近原始的cmd.exe
除了写得不好的批处理文件外,cd是唯一更改路径的命令吗?如果是这样,我可以检查该命令之后的路径。但是,我必须使用一个标签,因为从根发出的像dir*txt/s这样的命令可能需要一些时间,它不仅看起来愚蠢,在该输出的中间抛出路径,而且会使表单更少使用,甚至根本不显示路径。
或者让计时器每隔20秒左右启动另一个cmd.exe实例,以获取路径并将其显示在标签中。听起来像是浪费了很多周期却没有什么收获
在这一点上,最佳选择似乎迫使用户自己检查路径。我可以添加一个按钮来获取路径,使其更简单,但我更喜欢更好的解决方案。
p.WaitForExit()代码>您只是不知道,提示不可靠,您也不知道cmd.exe是否等待命令完成。如果started命令也接受输入,则“提前键入”不可靠。这需要以交互方式正常运行cmd.exe时的方式工作。用户只需等待程序完成,并且只有在知道安全的情况下才能提前输入。@Hans,这正是我所担心的。谢谢你的验证。为什么你需要这样的包装程序?如果我理解正确的话,您无论如何都是从包装程序启动cmd
,可能控制台窗口是隐藏的;为什么不在控制台窗口可见的情况下启动它,让管理员以通常的方式与之交互?(顺便说一句,在大多数情况下,阻止用户直接访问命令行的安全好处是最小的。)