私のアプリケーション(メインファイル)は、ShellExecuteEx
を使用して子プロセス(child.exe)を実行しています。親プロセスに応じて子プロセスを作成する方法は?
しかし、プロセスエクスプローラを使用して閉じる(プロセスエクスプローラ経由で)メインファイルは、子プロセスがアクティブのままです。 MAIN.EXEがchild.exeも終了終了したときに優雅に、それをどのように扱うか
?
私のアプリケーション(メインファイル)は、ShellExecuteEx
を使用して子プロセス(child.exe)を実行しています。親プロセスに応じて子プロセスを作成する方法は?
しかし、プロセスエクスプローラを使用して閉じる(プロセスエクスプローラ経由で)メインファイルは、子プロセスがアクティブのままです。 MAIN.EXEがchild.exeも終了終了したときに優雅に、それをどのように扱うか
?
jobsを使用する必要があります。メインの実行可能ファイルはcreate a job objectである必要があります。set JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSEにジョブオブジェクトのフラグを設定する必要があります。
uses
JobsApi;
//...
var
jLimit: TJobObjectExtendedLimitInformation;
hJob := CreateJobObject(nil, PChar('JobName');
if hJob <> 0 then
begin
jLimit.BasicLimitInformation.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, @jLimit,
SizeOf(TJobObjectExtendedLimitInformation));
end;
次に、あなたはdwCreationFlags
がCREATE_BREAKAWAY_FROM_JOB
に設定する必要がありますCreateProcess機能を持つ別のプロセスを実行する必要があります。この関数が成功した場合は、AssignProcessToJobObject
を呼び出します。
function ExecuteProcess(const EXE : String; const AParams: string = ''; AJob: Boolean = True): THandle;
var
SI : TStartupInfo;
PI : TProcessInformation;
AFlag: Cardinal;
begin
Result := INVALID_HANDLE_VALUE;
FillChar(SI,SizeOf(SI),0);
SI.cb := SizeOf(SI);
if AJob then
AFlag := CREATE_BREAKAWAY_FROM_JOB
else
AFlag := 0;
if CreateProcess(
nil,
PChar(EXE + ' ' + AParams),
nil,
nil,
False,
AFlag,
nil,
nil,
SI,
PI
) then
begin
{ close thread handle }
CloseHandle(PI.hThread);
Result := PI.hProcess;
end;
end;
//...
hApp := ExecuteProcess('PathToExecutable');
if hApp <> INVALID_HANDLE_VALUE then
begin
AssignProcessToJobObject(hJob, hApp);
end;
このすべてが実行されると、メインの実行可能ファイルが強制終了されても、すべての子プロセスが自動的に終了します。 JobsApiユニットhereを入手できます。注:私はDelphi 7でテストしていません。
EDIT:Here作業デモプロジェクトをダウンロードできます。
私はあなたのコードをテストしました。フォーム作成時に 'CreateJobObject'を使用しました。 'ExecuteProcess'のためのボタンを追加しました。子プロセスは正常に実行され、 'AssignProcessToJobObject'はTrueを返します。親アプリケーションを閉じると子プロセスは生き残ります。 – ZigiZ
@ zigi70おそらくあなたは何か間違っています。私たちはマルチモジュールソフトウェアでこの技術をうまく利用しています。私は自分の答えを編集し、作業デモプロジェクトのソースコードリンクを含めました。 – Linas
プロジェクト[ここ](http://www.4shared.com/zip/1yveHVAO/Jobs.html)をアップロードしました。あなたはとても親切で一見をいただけますか? – ZigiZ
Job Objects
を試してください。CreateJobObject
とAssignProcessToJobObject
を確認してください。
ジョブオブジェクトを使用すると、プロセスのグループを1つの単位として管理できます。ジョブ オブジェクトは、それに関連付けられたプロセスの属性を制御する、命名可能で、安全で、共有可能なオブジェクトです。ジョブオブジェクトに対して実行された操作 は、ジョブオブジェクトに関連付けられたすべてのプロセスに影響します。 例には、ワーキングセットサイズやプロセス の優先度の適用、またはのジョブに関連するすべてのプロセスの終了が含まれます()。
非常にクールなコードだと思います。それは私のために働いていますが、SW_SHOW/SW_HIDEのような子プロセスのウィンドウフラグを設定できるようにするためにいくつかの変更を加えました。
...
function ExecuteProcess(const EXE : String; const AParams: string = '';
const nCmdShow: Integer = SW_SHOW; AJob: Boolean = True): THandle;
var
SI : TStartupInfo;
PI : TProcessInformation;
AFlag: Cardinal;
begin
Result := INVALID_HANDLE_VALUE;
FillChar(SI,SizeOf(SI),0);
SI.cb := SizeOf(SI);
SI.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
SI.wShowWindow := nCmdShow;
if AJob then
AFlag := CREATE_BREAKAWAY_FROM_JOB
else
AFlag := 0;
...
は、メインの実行ファイルが閉じるときにメインの実行ファイルは、子の実行可能ファイルにメッセージを送信するには、Get。 –
メイン実行ファイルが終了したときには実行されません – ZigiZ
ジョブは優雅な解決策です。また、親プロセスハンドルを継承し、終了時にシグナルが送られるのを待つこともできます。 – OnTheFly