グラフィカルアプリケーションを作成する場合、外部プログラムを呼び出して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