ShellExecuteExプロセス(維持)の終了方法

解決


yTake  2015-07-31 02:01:15  No: 47507

yTakeです。
こちらを参照させて頂き、ShellExecuteExを用いてプロセスを開始出来る様になりました。
このプロセスの終了方法で困っています。
通常の、
TerminateProcess( hProcess, 0);
CloseHandle( hProcess );
で、終了できています。

ただ、本来ここでShellExecuteExで開始されるプロセスは、維持され、開始する際のフォームは先に終了されます。(fMask=SEE_MASK_NOCLOSEPROCESS)

そこで”hProcess”の値をファイルに保存してフォームは終了し、後に起動された時に、ファイルからhProcessの値を読み出しゼロでなければ必要に応じて
TerminateProcess( hProcess, 0);
CloseHandle( hProcess );
にて終了させる事を考えました。
はじめのうち数回は終了出来ていたのですが、動作確認を繰り返すうちに終了されなくなりました。

ただ、hProcessはTHandle型ですが、ファイルへ書き出す時や読み出す時にIntegerとして、処理して、hProcessへ代入している点が気になります。

ソースは抜粋ですが、
書き出し部
        str2  :=  IntToStr( hProcess );
        AssignFile( tf, fname );
        ReWrite( tf );
        WriteLn( tf, f_ddscp );
        WriteLn( tf, str2 );
        CloseFile( tf );

読み出し部
    AssignFile( tf, fname );
    Reset( tf );
    ReadLn( tf, str );
    f_ddscp :=  str;
    ReadLn( tf, str );
    hProcess  :=  StrToInt( str );
    CloseFile( tf );

終了部
        if hProcess <> 0 then
        begin
            TerminateProcess( hProcess, 0 );
            CloseHandle( hProcess );
            hProcess  :=  0;
        end;

となっています。

この様なhProcessをファイルへ書き出し読み出しするのは有効な手段でしょうか?

Windows7 32bit + DELPHI XE3
です。


yTake  2015-07-31 02:18:43  No: 47508

yTakeです。
補足です。

前述の他、念の為、

uses  ShellAPI;

hProcess : THandle;

jokさんご提示のルーチン
function  ExecAndGivehProcess( FileOrURL, params, workdir : string ) : THandle;
を引用一部修正させて頂いています。

THandle型の値をどの様にファイルへ書き出し読み込むべきかと言う風に考えています。

よろしくお願いします。


tor  2015-07-31 03:45:29  No: 47509

とりあえず一般論として、そういうプロセスを特定する用途にはハンドルじゃなくてプロセスノトとかを使うべきじゃないでしょうか。
もっとも、そのプロセスがまだ実行中であるという条件下でですが。

で、「〜開始されるプロセスは、維持され、開始する際のフォームは先に終了されます」という文の意味がいまいちよくとれなかったのですが、
・プログラムチはプログラムツを起動した後、自分自身は終了する
・次にチが起動した時、まだツが起動していたらツを終了させたい
ということでいいのでしょうか?ヲサそうだとして、後わからないことは
・次にチが起動した時、ツがまだ実行中であることは保障されている?ヲサすでにツが終了しているという可能性はないのか?
・ツは複数起動することはあるのか?
・チャヲサツヲサとも自作のプログラムか(両方とも自分でいじれるのか?)
といったあたりですね。これらの条件によって、どういう方法をとるか考えなくてはいけません。

例えば、どちらのプログラムも自分でいじれて、ツが複数起動しないという条件だとしたら、ツ自身に自分を終了させるという方法が考えられます。
アョヲサメラヘを使って、二つのプログラムの間だけで使う専用のメッセージを登録する
イョヲサプログラムチは、起動時にこのメッセージをブロードキャストする
ウョヲサプログラムツは、このメッセージを受け取ったら自分自身を終了させる(プログラムツがいない場合は何も起こらない)

このような方法が使えないとした場合、
プロセスハンドルやノトでは、対象のプロセスがすでに終了していた場合
「まだこの情報は有効か」を確かめることができません。
なので、何か別の方法で対象を特定する必要がありますね。例えばウィンドウのクラス名ヲサタイトルとか、実行ファイル名とか。
スススススススススススススススススススススススススススススススススススススススス
ニコ yヤ
トコ イーアオッーキッウアィ金ゥ ークコエクコイア  書込者ノト:ロ 「。、「 ン

さん
ありがとうございます。
確かにハンドルに固執する必要はありません。プロセスノトでも良いです。
ただ、先に実現できた手順がハンドルによるものだったわけです。
ご指摘の通り、プログラムAとBの状態は単純ではありません。
因みに、Aは自作ですが、Bは既存のコマンドになります。

次回Aが起動された時にBが稼働中であるかどうかは確定的ではありません。通常は、Bは終了しないのですが、PC自体が再起動されてしまうと、再起動後はBは当然起動していません。しかし、Aがファイルに記録した状態は稼働中のままです。
これは、ハンドル、プロセスIDいずれかを記録しても同じだと思われます。

より良いと思われるのは、Bの実行状態をBのプログラム名で確認できる事と考えられます。
実行中のプログラムのリストを得られないか調べてみます。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
ネミコ コッッョョョッュットツツモッョソォイーーエーエッーエーエーーキカョ
トコ イーアオッーキッウアィ金ゥ アエコーイコエク シ  スュアセシ上級者セ シッニセシノヘヌ ス「コッッョョョッッウョ「 ス「ー「セ 書込者ノト:ロ 」。ァ」。 ン

偶然だとは思いますが
以前同様の質問をしていました。アー年以上前・・・

コッッョョョッュットツツモッョソォイーーエーエッーエーエーーキカョ

結局のところ

プログラムAからプログラムBを起動する  ○
プログラムAからプログラムBを終了させる  ○?

「hミをファイルに書き出す」ということは

プログラムAからプログラムBを起動させ
プログラムAが終了
その後プログラムAを起動

この状態では前のプロセスノトを覚えていないので
「確認」「終了」が出来ないので値を保存すれば
いいのではないか?

ということですかね?

やりたい動作がわからないと話が広がりすぎそうです。
スススススススススススススススススススススススススススススススススススススススス
ニコ yTake
トコ イーアオッーキッウアィ金ゥ アオコークコアオ  書込者ノト:ロ 「。、「 ン

さん
ありがとうございます。
いえいえ、まさしく参照させて頂きました。
やりたい事はご指摘の通りです。

ミをファイルへ書き出し、プログラムAを終了します。
プログラムAを再起動後、ファイルからミを読み込み、
ヤミィヲサミャヲサーヲサゥサ
としましたが、プログラムBが終了してくれません。

プログラムAを終了せずに、
ヤミィヲサミャヲサーヲサゥサ
とすると、プログラムBは終了します。

つまり、ネ型であるミは正しく取得できているが、ファイルに書き出し読み込む間に、ノ型になっている為、
ミの値をノ型で代入しても無効なのかな?と考えています。

また、根本的にプロセスノト等をファイルに書き出し保持する方法自体に問題があり、次回プログラムAが起動されるまでの間のプログラムBの状態変化が反映しない点です。

従いまして、プログラムBのプロセスIDをプログラムBの名前で現在稼動中のプロセスリストから探し出して、存在すればそれを終了し、存在しなければ何もしない。と言うのが理想と言えます。
稼働中のプロセスのリストを得る方法を検討中です。

この様な方向性で問題ないでしょうか?
スススススススススススススススススススススススススススススススススススススススス
ニコ プロセスハンドル≠プロセスノト
トコ イーアオッーキッウアィ金ゥ アオコイアコエイ  書込者ノト:ロ 」「。   ン

全てのハンドルは一部の例外を除いてプロセスが終了する時にマモが解放します。
よってプログラムチを終了した時点で書き出したミの値は無効化されるため、
再度読み出したところで無効なハンドルであり、使用できてもそれは偶然に過ぎません。
根本的にラの仕組みを理解されていないと思われますので、
ラチミノの解説書などで勉強されることをお勧めします。
スススススススススススススススススススススススススススススススススススススススス
ニコ yヤ
トコ イーアオッークッーアィ土ゥ アアコアアコエク  書込者ノト:ロ 「「・。 ン

ご指摘ごもっともです。
ネ型の確認くらいは出来ましたね。
符号無し整数がその実態と言う事ですので、ノ型での書き出し読み込み自体は問題ないと理解しました。

実は、再起動後のプログラムAから、保存されたミ値を用いてプログラムBを終了する事が出来た事もありました。
この時、
ヤミィヲサミャヲサーヲサゥサで、プログラムBが終了し、
テネィヲサミヲサゥサでは、エラーが生じていました。
他方、プログラムAを終了する前の時点で、プログラムBをミで終了させた場合、
ヤミィヲサミャヲサーヲサゥサで、プログラムBが終了し、
テネィヲサミヲサゥサでも、特にエラーはありませんでした。

つまり、ミとしてファイルに保存する値は、
従いまして、ハンドルはウィンドゥが終了する時に破棄されるのだろうとは思われました。

ただ、このhミはプログラムBの値として生成させたはずです。プログラムBは終了していない為、有効だと思うのですが、
モナナの引数としての構造体に、プログラムBを指定しています。
この場合でも、プログラムAを終了すると、プログラムBは終了していないににも関わらず、ミは無効なのでしょうか?
私の理解不足なのでしょう。
==============
ヲサヲサナチヌミィヲサャヲサャヲサヲサコヲサヲサゥヲサコヲサヤネサ

ヲサヲサヲサコヲサヤモナノサ

ヲサヲサニティヲサャヲサモマィヲサヤモナノヲサゥャヲサ」ーヲサゥサ
ヲサヲサョモヲサヲサヲサヲサヲサヲサヲサヲサコスヲサヲサモマィヲサヤモナノヲサゥサ
ヲサヲサョヘヲサヲサヲサヲサヲサヲサヲサヲサヲサコスヲサヲサモナナ゜ヘチモピホマテフマモナミメマテナモモサ
ヲサヲサョラヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサコスヲサヲサニウョネサ
ヲサヲサョニヲサヲサヲサヲサヲサヲサヲサヲサコスヲサヲサミティヲサヲサゥサ
ヲサヲサョミヲサヲサコスヲサヲサミティヲサヲサゥサ
ヲサヲサョトヲサヲサヲサコスヲサヲサミティヲサヲサゥサ
ヲサヲサョモヲサヲサヲサヲサヲサヲサヲサヲサヲサコスヲサヲサモラ゜モネマラホマメヘチフサ
ヲサヲサヲサモナナィヲサタヲサゥヲサ
ヲサヲサヲサヲサヲサコスヲサョミ
ヲサヲサ
ヲサヲサヲサヲサヲサコスヲサーサ

==============
の様にコーディングしています。
として、モで実行するコマンドをに記述した引数で呼び出し、このミを保存しているのですが、、、

ラチミノを勉強してみます。
スススススススススススススススススススススススススススススススススススススススス
ニコ ヒネナーーイイア
トコ イーアオッークッーアィ土ゥ アクコオエコーエ  書込者ノト:ロ 「「、・「 ン

ヲサヲサミノトヲサコスヲサヌミノトヲサィョミゥサ

でヲサミノトヲサを保存してヲサ

ヲサヲサネコヲサトラマメト

ヲサヲサネヲサコスヲサマミィミメマテナモモ゜チフプチテテナモモャヤャミノトゥサ
ヲサヲサヤミィネャーゥサ

ミノトでプロセス終了
スススススススススススススススススススススススススススススススススススススススス
ニコ yTake
トコ イーアオッークッーウィ月ゥ ーーコウアコーウ  書込者ノト:ロ 「「・。 ン

ヒネナーーイイアさん、ありがとうございます。
みなさんのおかげで、ファイルへ書き出す事無く、プログラムAからどのタイミングでも、プログラムBを終了出来る様に出来ました。

プログラムAの起動時にコマンド名でプロセスを探索し、みつかったプロセスIDからハンドルを得て、それを終了させる事で、うまく行きました。
ありがとうございました。
ヘリメさんのページが大変参考になりました。

大変ありがとうございました。
スススススススススススススススススススススススススススススススススススススススス
ニコ yヤ
トコ イーアオッーケッイカィ土ゥ アケコアクコオオ シ  スュアセシ初心者セ シッニセシノヘヌ ス「コッッョョョッッアョ「 ス「ー「セ 書込者ノト:ロ 「「・。 ン

すみません。
解決のチェックを付けていませんでした。

皆様、ありがとうございました。
スススススススススススススススススススススススススススススススススススススススス
ニコ yヤ
トコ イーアオッーケッイカィ土ゥ アケコアケコエク  書込者ノト:ロ 「「・。 ン
モコ 

すみません。
解決のチェックを付けていませんでした。

皆様、ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加