当使用AllocConsole
或AttachConsole
打开控制台窗口后,关闭该窗口将导致关联的进程退出。无法逃脱这种情况。
在Windows Vista之前,关闭控制台窗口会向用户显示一个确认对话框,询问是否终止该进程,但是Windows Vista及更高版本没有提供任何此类对话框,进程将被终止。
解决此问题的一种方法是避免使用 AttachConsole,并通过其他方式实现所需功能。
例如,在OP所描述的情况下,需要使用Console
静态类在控制台上输出一些文本。
可以很容易地通过进程间通信实现此目的。例如,可以开发一个控制台应用程序作为回声服务器。
namespace EchoServer
{
public class PipeServer
{
public static void Main()
{
var pipeServer = new NamedPipeServerStream(@"Com.MyDomain.EchoServer.PipeServer", PipeDirection.In);
pipeServer.WaitForConnection();
StreamReader reader = new StreamReader(pipeServer);
try
{
int i = 0;
while (i >= 0)
{
i = reader.Read();
if (i >= 0)
{
Console.Write(Convert.ToChar(i));
}
}
}
catch (IOException)
{
}
finally
{
pipeServer.Close();
}
}
}
}
然后,不要为当前应用程序分配或附加控制台,可以从应用程序内部启动回显服务器,并将Console
的输出流重定向以写入管道服务器。
class Program
{
private static NamedPipeClientStream _pipeClient;
static void Main(string[] args)
{
//Current application is a Win32 application without any console window
var processStartInfo = new ProcessStartInfo("echoserver.exe");
Process serverProcess = new Process {StartInfo = processStartInfo};
serverProcess.Start();
_pipeClient = new NamedPipeClientStream(".", @"Com.MyDomain.EchoServer.PipeServer", PipeDirection.Out, PipeOptions.None);
_pipeClient.Connect();
StreamWriter writer = new StreamWriter(_pipeClient) {AutoFlush = true};
Console.SetOut(writer);
Console.WriteLine("Testing");
//Do rest of the work.
//Also detect that the server has terminated (serverProcess.HasExited) and then close the _pipeClient
//Also remember to terminate the server process when current process exits, serverProcess.Kill();
while (true)
continue;
}
}
这只是可能的解决方案之一。实质上,解决方法是将控制台窗口分配给它自己的进程,以便可以终止而不影响父进程。
FreeConsole
不应该结束整个应用程序/进程。您应该能够调用FreeConsole
,然后稍后调用AllocConsole
或AttachConsole
。 - Cody Gray