AllocConsole
またはを使用して取得したコンソールウィンドウを閉じるAttachConsole
と、関連するプロセスが終了します。それから逃れることはできません。
Windows Vistaより前では、コンソールウィンドウを閉じると、プロセスを終了するかどうかを尋ねる確認ダイアログがユーザーに表示されますが、Windows Vista以降ではそのようなダイアログが表示されず、プロセスが終了します。
これを回避するための1つの可能な解決策は、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)
{
//error handling code here
}
finally
{
pipeServer.Close();
}
}
}
}
次に、コンソールを現在のアプリケーションに割り当て/接続する代わりに、アプリケーション内からエコーサーバーを起動し、Console's
出力ストリームをリダイレクトしてパイプサーバーに書き込むことができます。
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;
}
}
これは、考えられる解決策の1つにすぎません。基本的に、回避策は、コンソールウィンドウを独自のプロセスに割り当てて、親プロセスに影響を与えずに終了できるようにすることです。