5

我一直在忙于编写一个用作前端的应用程序:它有一个 GUI,带有按钮之类的命令行选项,并将它们传递给命令行 .exe。它使用应用程序的控制台来显示命令行应用程序的输出。这很好用,但是当使用 Ctrl+C 或尝试关闭控制台窗口时,GUI 也会关闭,这并不是我真正想要的。但是,让程序输出带有它自己的控制台是不可能的,因为它批处理文件并且每个文件都会弹出它自己的控制台。

该程序是用 C++ 和 MSVC 2012 编写的,并使用 .NET。我试过 Console::CancelKeyPress 至少让 Ctrl+C 表现得像我想要的那样(停止命令行应用程序而不是 GUI),但在这方面遇到了一些问题。

我的代码

private: System::Void OnCancelKeyPressed(System::Object^  sender, System::ConsoleCancelEventArgs^  e) {
         e->Cancel = true;
     }
private: System::Void GetConsoleReady() {
         COORD c;
         FreeConsole();
         AllocConsole();
         c.X = 80; c.Y = 8000;
         SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),c);
         Console::Clear();
         Console::TreatControlCAsInput = false;
         Console::CancelKeyPress += 
             gcnew ConsoleCancelEventHandler(this, &Form1::OnCancelKeyPressed);  
     }

每次用户尝试运行一批要处理的文件时都会调用它。运行批处理后,使用 FreeConsole() 释放控制台。第一次运行良好,使用 Ctrl+C 会杀死命令行应用程序,但 GUI 中的处理继续,运行其他命令,最后使用 FreeConsole()。但是,当第二次尝试这样做时,它也会杀死 GUI。我尝试在添加新事件之前添加它以删除以前的事件

             Console::CancelKeyPress -= 
             gcnew ConsoleCancelEventHandler(this, &Form1::OnCancelKeyPressed);  

但不知何故,在添加处理程序时会引发错误,但只是第二次:mscorlib.dll 中发生了“System.IO.IOException”类型的未处理异常,附加信息:De 参数是 onjuist。

最后一部分是荷兰语的“错误参数”,调试器说它在读取 ConsoleCancelEventHandler 时窒息。

如果我尝试通过在加载表单时添加它来仅添加一次事件处理程序,它什么也不做。

这里发生了什么?

4

1 回答 1

0

您是否考虑过在不同的过程中运行批处理?然后,您可以通过读取衍生进程的标准输出(和标准错误)来显示批处理的输出。

如果您使用的是 .net,请查看 Process.RedirectStandardOutput(此处为Capturing console output from a .NET application (C#) 的示例)。

如果您隐藏生成的进程,则用户无法与之交互/关闭它。您的主应用程序仍然处于完全控制之下,并且 ctrl-c 等没有问题。

于 2014-02-27T19:57:50.013 回答