COM オートメーションで プロセスが落ちない

解決


よっち  2007-04-04 15:56:03  No: 64854  IP: 192.*.*.*

VisualC++.NET2003 を使って アプリAを操作するアプリBを製作して
おります。アプリAはCOMオートメーション機能が備わっております。

アプリB側でアプリAのインスタンスを取得して
設定や状態取得などのメソッド実行は、うまく動作しています。

さて、この状態で、アプリAを×印等で終了したとき、
アプリAのウィンドウは無くなるものの、タスクマネージャからみると、
アプリAが生きているようです。
どうにかして、アプリAを落としたいと思っております。

アプリB側では、今のところ アプリAの終了イベントをキャッチ
しておらず(これが原因??)
設定や状態取得コマンドの戻り値が S_OK では無いときに
Release() を呼んでみましたが、相変わらずアプリAは生き続けています。

VBで制御すると、以下のようにすると、簡単にアプリAのイベントを
拾えるようです。
(この関数を準備するだけで、呼び出されるようになるのかな?)
*Description
 Notifies that EchoLink is closing down, and all references are no longer valid. 
*Syntax
 Private Sub object_Closing()

C++ ではどうやってこのイベントを取得できるのか、
調べているところですが、まだしっくり来ていないのが現状です。
DIID__IEchoLinkSessionEvents 辺りを何がすれば、出来るのかな?
といった状況です。

お気づきの点がございましたら、ご指摘いただけませんでしょうか?
よろしくお願いします。


・echolink.tlh ファイルは以下のURLに置きました。
http://jm7muu.mydns.jp/index.php?plugin=attach&pcmd=open&file=echolink.tlh.txt&refer=SoftTSQ-bugtrack%2F5
・アプリAのAPIリファレンスは以下にあります。
http://www.hfremote.us/files/API.zip

編集 削除
シャノン  2007-04-05 09:45:14  No: 64855  IP: 192.*.*.*

> さて、この状態で、アプリAを×印等で終了したとき、
> アプリAのウィンドウは無くなるものの、タスクマネージャからみると、
> アプリAが生きているようです。

まだアプリBがアプリAを使っているのに終了しちゃったら困りますよね。
アプリBが、もうアプリAを必要としなくなった段階で、すべての参照を Release すれば消えませんか。

編集 削除
よっち  2007-04-05 22:26:54  No: 64856  IP: 192.*.*.*

シャノンさんコメント有難う御座います。

そうなんですよね。何かが残っているのかとおもって、
追いかけていますが、未だに謎のままです。

CoCreateInstance を行っているのは一回で、
そこで得た インタフェースポインタをつかって、
Release()を実行しています。
戻り値は S_OK となっていますので、成功?とおもいきや、
タスクは残ったままのようです。

Release()にbreak をかけて、単発で実行してみました。
まずは、アプリAを終了せずに、アプリBからReleaseをかけてから、
アプリAを終了させると、無事に アプリAが落ちます。

今度は、アプリAを×印で終了させてから、アプリBからRelease を
かけても、アプリAのタスクは残ったままとなってしまいます。

いずれも Releaseの戻り値は S_OK となっています。
なんでしょうね・・・

終了イベントを捕まえないとNGなのでしょうかね。

編集 削除
よっち  2007-04-05 22:31:30  No: 64857  IP: 192.*.*.*

頻繁にアプリAに問いかけるようになっていますが、
CoCreateInstance や Release を毎回実行する必要はないのですよね?

一番最初にCoCreateInstance を実行して、
何度もアプリAに問いかけたり、設定をしたりしています。
本当にもう使用しないときに、 Release を行っていますが、
あやまった使い方でしょうか?

編集 削除
渋木宏明(ひどり)  URL  2007-04-06 10:21:14  No: 64858  IP: 192.*.*.*

>終了イベントを捕まえないとNGなのでしょうかね。

んなこたしません。

既にコメントがついているように、アプリBがアプリAを使っているのに、アプリAが勝手に終了してしまったら、もっと都合の悪いことになります。

アプリAをオートメーション起動した場合、アプリAに対して、通常はユーザ操作を許してはいけません。

Office アプリなんかは、オートメーション起動した場合デフォルトでアプリケーションウィンドウは非表示だったはずです。

オートメーション起動したアプリの終了方法は、アプリケーションごとに微妙に異なります。

Office 系のアプリについて言えば、

・Quit() メソッドを実行
・オートメーション起動に使用したアプリケーションのインターフェースポインタに対して Release() を実行

とするのがならわしです。

アプリAの正式な終了手順については、アプリAの資料を参照してください。

ただし、「正式な終了手順」を踏んでいたとしても、アプリAをオートメーションする上で使用したインターフェースポインタに1個でも Release() し忘れがあると、アプリAは終了しません。

>本当にもう使用しないときに、 Release を行っていますが、
>あやまった使い方でしょうか?

特に問題ありません。

編集 削除
シャノン  2007-04-08 16:28:40  No: 64859  IP: 192.*.*.*

> いずれも Releaseの戻り値は S_OK となっています。

Release の戻り値は HRESULT ではありませんが…
S_OK って中身は 0 でしたっけ。0 なら OK ですね。

> まずは、アプリAを終了せずに、アプリBからReleaseをかけてから、
> アプリAを終了させると、無事に アプリAが落ちます。

> 今度は、アプリAを×印で終了させてから、アプリBからRelease を
> かけても、アプリAのタスクは残ったままとなってしまいます。

この2つのケースで、アプリBには全く変更がなく、アプリAを先に終了させるかどうかの違いだけなら、アプリAのマニュアルを見るか、書いてなければ製作元に問い合わせた方がいいかもしれません。

編集 削除
よっち  2007-04-11 13:39:30  No: 64860  IP: 192.*.*.*

ひどりさん、シャノンさん
コメント有難う御座います。
とても勉強になりました。

まずは、アプリAの使い方として、
アプリBから操作中でもアプリAの操作ができてしまう
作りになっているようです。
状態を監視する時などは、タイミングミスマッチが
おきることもありますよね。
そういうソフトウェアのようです。

色々しらべていったら、アプリAを操作するアプリが
複数あることも分かってきました。
それを平行して動作させている方もいるらしいです。
操作されるアプリAの中で矛盾しないのか、
操作しているアプリとしても、非常に疑わしい限りです。

とりあえず、アプリAにメッセージを送る前に、
CoCreateInstance や、CoGetInstance 等を行なうようにしました。
おわったら、即 Release すれば、今のところ大丈夫そうです。

既にアプリAが落ちている時に、CoCreateInstance を投げると、
アプリAが勝手に立ち上がってしまいますが、
どちらかというと、アプリAやアプリBは常時起動していて欲しい
システムで使用されるため、好都合となりました。

んー。本来の使い方では無いと思いますので、
アプリAの設計者にお尋ねしてみたいと思います。

とりあえず本件は、解決済みとさせて頂きたいと思います。
有難う御座いました。<m(__)m>

編集 削除