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

解決


よっち  2007-04-05 00:56:03  No: 64854

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 18:45:14  No: 64855

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

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


よっち  2007-04-06 07:26:54  No: 64856

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

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

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

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

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

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

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


よっち  2007-04-06 07:31:30  No: 64857

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

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


渋木宏明(ひどり)  URL  2007-04-06 19:21:14  No: 64858

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

んなこたしません。

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

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

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

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

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

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

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

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

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

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

特に問題ありません。


シャノン  2007-04-09 01:28:40  No: 64859

> いずれも 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 22:39:30  No: 64860

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

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

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

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

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

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

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


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

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






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