是否可以将来自WinForms应用程序的消息记录到以编程方式启动的cmd.exe进程?我尝试过以下代码的各种变体:
private void button1_Click(object sender, EventArgs e)
{
Log("Button has been pressed");
}
private void Log(string message)
{
var process = Process.Start(new ProcessStartInfo("cmd.exe", @"/K ""more""")
{
UseShellExecute = false,
RedirectStandardInput = true,
});
process.StandardInput.WriteLine(message);
}
不幸的是,控制台窗口闪烁了半秒钟,就是这样。
请不要回答我真正想做的事情,因为现在我只是好奇是否可能:)
答案 0 :(得分:6)
你很幸运。我刚刚解决了这个我在这里漂浮的代码生成器玩具项目。
使用AttachConsole
或AllocConsole
Win32 API,您可以像通常那样使用System.Console.WriteLine
(或Read或Error.WriteLine等)来实现结果。
以下代码段显示从控制台窗口启动表单应用程序并附加到其父控制台时;如果这不起作用,它将创建它自己的控制台,并记住保持打开(例如,在用户可以读取输出之前它不会消失。)
[DllImport("kernel32.dll")] static extern bool AllocConsole();
[DllImport("kernel32.dll")] static extern bool AttachConsole(int pw);
private static bool _hasConsole, _keepConsoleOpen;
static private void EnsureConsole()
{
_hasConsole = _hasConsole || AttachConsole(-1);
_keepConsoleOpen = !_hasConsole || _keepConsoleOpen;
_hasConsole = _hasConsole || AllocConsole();
}
[STAThread]
private static void Main(string[] args)
{
EnsureConsole();
// the usual stuff -- your program
if (_keepConsoleOpen)
{
Console.WriteLine("(press enter)...");
Console.Read();
}
}
答案 1 :(得分:2)
不是最终答案,但至少应该有所帮助:
首先,在Log例程之外声明该进程,以便在您想要记录更多内容时不会超出范围。
无论如何,我尝试了以下方法:
Process process = Process.Start(new ProcessStartInfo("cmd.exe", "/K more") {
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardError = true,
RedirectStandardOutput = false
});
private void button1_Click(object sender, EventArgs e) {
Log("Button has been pressed");
MessageBox.Show(process.StandardError.ReadToEnd());
}
private void Log(string message) {
process.StandardInput.WriteLine(message);
}
单击按钮后,您的应用程序将挂起(它正在等待控制台关闭,ReadToEnd字面读取到最后)。当您关闭控制台时,您将收到一个带有错误输出的消息框:
The handle is invalid.
The handle is invalid.
The handle is invalid.
'Button' is not recognized as an internal or external command,
operable program or batch file.
The handle is invalid.
The handle is invalid.
在运行CMD时,似乎无法仅重定向输入而不重定向输出。我不知道为什么,也许尝试不同的命令行选项会有所帮助。我还尝试删除更多命令并记录“dir”:
Log("dir");
结果有点吓人:
The handle is invalid.
...
There is not enough space on the disk.
The handle is invalid.
The handle is invalid.
有趣的我必须说!看起来你已经开了一罐蠕虫: - )
答案 2 :(得分:1)
打印到控制台后必须插入暂停命令。
一旦命令执行,进程就会终止,导致你看到闪烁。
答案 3 :(得分:0)
据我所知,我相信你会让CMD正确开启。但是一旦执行该命令,控制台就会终止。这是正常的行为。
如果你执行.bat / .cmd,你可以编写多个命令的脚本,如果你在命令之后做了一个“暂停”,你应该能够看到在控制台终止之前发生了什么。
答案 4 :(得分:0)
我认为如果您将项目构建为“控制台应用程序”,您将获得控制台并仍可以打开Windows窗体。创建“控制台应用程序”类型的新项目。将Windows窗体添加到项目中。在Program.cs的Main函数中,使用以下代码实例化并显示表单:
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
我不确定这是否是理想的做法。但它确实有效。