私は知っています、これは古いスレッドですが、私はこれに対する素晴らしい解決策を持っています。
バッチファイルをいじくり回す必要はありません。秘訣はexeの種類にあり、それはサブシステム属性です。exeをGUIアプリケーションとしてコンパイルした後({$ APPTYPE CONSOLE}ディレクティブなしで、そのサブシステム属性IMAGE_SUBSYSTEM_WINDOWS_GUIをIMAGE_SUBSYSTEM_WINDOWS_CUIに変更する必要があります。コンソールからコンソールアプリを実行すると、追加のコンソールウィンドウが表示されません。その時点では、「Enterキーを押してウィンドウを閉じる」などのメッセージは必要ありません。編集:私のプロジェクトで行ったように、コンソールアプリ内で別のコンソールアプリを起動する場合)
エクスプローラーなどからクリックまたはstart|runで実行すると、サブシステム属性がIMAGE_SUBSYSTEM_WINDOWS_CUIの場合、Windowsは自動的にコンソールウィンドウを開きます。{$APPTYPECONSOLE}ディレクティブを指定する必要はありません。すべてはサブシステム属性に関するものです。
RRUZのソリューションは、私も使用しているソリューションですが、重要な違いが1つあります。親プロセスのサブシステムをチェックして、「Enterキーを押してこのウィンドウを閉じます」と表示します。RUZZのソリューションは、cmdまたはexplorerの2つの場合にのみ機能します。親プロセスの属性がNOTIMAGE_SUBSYSTEM_WINDOWS_CUIであるかどうかを確認するだけで、メッセージを表示できます。
しかし、exeサブシステムをチェックする方法は?PEヘッダー情報を取得して2つの関数setExeSubSys()とgetExeSubSys()に変更するための、トーリーのヒント(http://www.swissdelphicenter.ch/torry/showcode.php?id=1302 )の解決策を見つけました。setExeSubSys()を使用して、コンパイル後にexeのサブシステム属性を変更できるように小さなコンソールアプリを作成しました(わずか50 kbです!)。
親/潜在的なプロセスファイル名を取得したら、次のように簡単に実行できます。
//In the very beginning in the app determine the parent process (as fast as is possible).
// later on you can do:
if( getExeSubSys( parentFilename ) <> IMAGE_SUBSYSTEM_WINDOWS_CUI ) then
begin
writeln( 'Press Enter to close the window' );
readln;
end;
これが私が作った2つの関数ですが、ストリームでは機能しません(torryの例のように)、私は愚かな例外のないものなしでそれのためのファイルのために私自身の簡単なユニットを使用します。しかし、基本的に私はあなたがそれの周りの考えを得ると思います。
設定するには(また、longint(nil)へのポインターを指定しない場合に取得するため):
type
PLongInt = ^LongInt;
function setExeSubSys( fileName : string; pSubSystemId : PLongInt = nil ) : LongInt;
var
signature: DWORD;
dos_header: IMAGE_DOS_HEADER;
pe_header: IMAGE_FILE_HEADER;
opt_header: IMAGE_OPTIONAL_HEADER;
f : TFile;
begin
Result:=-1;
FillChar( f, sizeOf( f ), 0 );
if( fOpenEx( f, fileName, fomReadWrite )) and ( fRead( f, dos_header, SizeOf(dos_header)))
and ( dos_header.e_magic = IMAGE_DOS_SIGNATURE ) then
begin
if( fSeek( f, dos_header._lfanew )) and ( fRead( f, signature, SizeOf(signature))) and ( signature = IMAGE_NT_SIGNATURE ) then
begin
if( fRead( f, pe_header, SizeOf(pe_header))) and ( pe_header.SizeOfOptionalHeader > 0 ) then
begin
if( fRead( f, opt_header, SizeOf(opt_header))) then
begin
if( Assigned( pSubSystemId )) then
begin
opt_header.Subsystem:=pSubSystemId^;
if( fSeek( f, fPos( f )-SizeOf(opt_header) )) then
begin
if( fWrite( f, opt_header, SizeOf(opt_header)) ) then
Result:=opt_header.Subsystem;
end;
end
else Result:=opt_header.Subsystem;
end;
end;
end;
end;
fClose( f );
end;
取得するため:
function GetExeSubSystem( fileName : string ) : LongInt;
var
f : TFile;
signature : DWORD;
dos_header: IMAGE_DOS_HEADER;
pe_header : IMAGE_FILE_HEADER;
opt_header: IMAGE_OPTIONAL_HEADER;
begin
Result:=IMAGE_SUBSYSTEM_WINDOWS_CUI; // Result default is console app
FillChar( f, sizeOf( f ), 0 );
if( fOpenEx( f, fileName, fomRead )) and ( fRead( f, dos_header, SizeOf(dos_header)))
and ( dos_header.e_magic = IMAGE_DOS_SIGNATURE ) then
begin
if( fSeek( f, dos_header._lfanew )) and ( fRead( f, signature, SizeOf(signature))) and ( signature = IMAGE_NT_SIGNATURE ) then
begin
if( fRead( f, pe_header, SizeOf(pe_header))) and ( pe_header.SizeOfOptionalHeader > 0 ) then
begin
if( fRead( f, opt_header, SizeOf(opt_header))) then
Result:=opt_header.Subsystem;
end;
end;
end;
fClose( f );
end;
サブシステムで詳細情報が必要な場合は、グーグルで検索するか、MSDNWebサイトにアクセスしてください。それが誰にとっても役に立ったことを願っています。
グリーツ、アーウィン・ハンチェス