IPC :: Open3。 STDERRで問題を解決する

グラフィカルアプリケーションを作成する場合、外部プログラムを呼び出してSTDOUT / STDERRから読み取る必要が生じることがあります。

IPC :: Open3モジュールは、 これについて素晴らしい仕事をます。



ただし、作成したプログラムはすべて機能しますが、ユーザー(またはユーザー)に不要なターミナルウィンドウを表示させたくありません。



非表示にするオプションがいくつかあります。



1. perl.exeではなくwperl.exeを使用してスクリプトを実行します

2. ???



プログラムを検討する

厳格な使用;

 Tkxを使用します。
 use IPC :: Open3;

 my $ mw = Tkx :: widget-> new( '。');
私の$ tw = $ mw-> new_text();

私の$ bt = $ mw-> new_ttk__button(
     -text => 'dir'、
     -command => sub {
         my($ rdr、$ pid);
         $ pid = open3(undef、$ rdr、undef、 'dir');
         $ tw-> insert( 'end'、do {local $ /; <$ rdr>});
     }、
 );

 Tkx :: pack($ tw);
 Tkx :: pack($ bt);

 Tkx :: MainLoop;




画像



dirコマンドが呼び出され、その結果が表示されます。 (エンコードを無視します)。



すべて動作しますが、wperl.exeを使用してスクリプトを実行すると、open3を呼び出すとエラーが発生します。

 open3:C:/perl5.8/lib/IPC/Open3.pm行368の未定義の値に対してメソッド「close」を呼び出すことはできません。

 open3:C:/perl5.8/lib/IPC/Open3.pm行368の未定義の値に対してメソッド「close」を呼び出すことはできません。




問題は、wperlが標準スレッド (STDIN、STDOUT、STDERR)を作成しないことです。



私は長い間、プログラムを機能させる方法に戸惑いました。 プログラムの本体内でWINAPIを呼び出し、batを介してファイルを実行しようとしましたが(すべてのプログラムで機能するわけではありません)、解決策は簡単な驚きでした。



SW_HIDE属性を使用してshell32.dllのShellExecute関数を使用する必要があります。



以下はCのローダーコードです。

 #include <stdio.h>
 #include <windows.h>

 static char * ldr_file = "app.pl";
 static char * ldr_path = "";

 int main(int argc、char * argv [])
 {
   intコード;
   LoadLibrary( "shell32.dll");
  
   code =(int)ShellExecute(NULL、 "open"、ldr_file、ldr_path、NULL、SW_HIDE);
   if(コード<= 32)
   {
	 char buf [200];
	 sprintf(buf、「アプリケーションを実行できません。コード:%d」、コード);
	 MessageBox(
		 NULL
		バフ
		 「Dynld Error」、
		 MB_ICONERROR |  MB_OK
	 );
   }

  リターンコード;
 }




MinGWからgccをコンパイルします。

gcc -mwindows loader.c -o loader.exe










All Articles