« 標準出力と標準エラーを入れ替えられるか? | トップページ | バッチファイルをウィンドウアプリっぽくする。 »

2007年9月 3日 (月)

標準出力と標準エラーを非同期にMessageBoxに出す。

先のコンソールアプリ版のMessageBox.exeでは、

hogehoge 2>&1 | MessageBox.exe

MessageBoxを閉じるまで、コンソールが開いたままだし、処理も止まります。

(hogehoge | MessageBox.exe) 2>&1 | MessageBox.exe

標準出力のMessageBoxを閉じるまで、標準エラーのMessageBoxが出ません。

どうもパイプの前のプロセスにパイプのハンドルの複製が残っているのでは?
なので、プロセスを終了しないとパイプのEOFが上がらない。。。

そこで、別にプロセスを起こして自分は終了するとよいようです。
ProcessStartInfo.UseShellExecute=trueでプロセスを起こすと、
ファイルハンドルを引き継がないようです。

MessageBox.JS

import System;
import System.IO;
import System.Diagnostics;
import System.Windows.Forms;
var Args:String[]=Environment.GetCommandLineArgs();
try{
  var CommandLine:String=Environment.CommandLine;
  if(CommandLine.StartsWith('"')){
    var startIndex=CommandLine.IndexOf('"',1);
    if(0<startIndex && startIndex+2<CommandLine.Length){
      CommandLine=CommandLine.Substring(startIndex+2);
    }else{
      CommandLine="";
    }
}else{
    var startIndex=CommandLine.IndexOf(' ');
    if(-1<startIndex && startIndex+1<CommandLine.Length){
      CommandLine=CommandLine.Substring(startIndex+1);
    }else{
      CommandLine="";
    }
  }
  if(CommandLine.Length){
    Environment.Exit(MessageBox.Show(CommandLine,Path.GetFileName(Args[0])));
  }
  CommandLine=Console.In.ReadToEnd();
  if(!CommandLine.Length)CommandLine="[EOF]";
  var startInfo:ProcessStartInfo=new ProcessStartInfo();
  startInfo.FileName=Args[0];
  startInfo.Arguments=CommandLine;
  Process.Start(startInfo);
  Environment.Exit(0);
}catch(e){
  MessageBox.Show(e.ToString(),Path.GetFileName(Args[0]),MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
  Environment.Exit(99);
}

これを
jsc /t:winexe MessageBox.JS
でコンパイルします。

これだと、MessageBoxを出したまま、次の処理に移ったり、
コンソールウィンドウを先に閉じたり、出来ます。:-)

« 標準出力と標準エラーを入れ替えられるか? | トップページ | バッチファイルをウィンドウアプリっぽくする。 »