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
> さて、この状態で、アプリAを×印等で終了したとき、
> アプリAのウィンドウは無くなるものの、タスクマネージャからみると、
> アプリAが生きているようです。
まだアプリBがアプリAを使っているのに終了しちゃったら困りますよね。
アプリBが、もうアプリAを必要としなくなった段階で、すべての参照を Release すれば消えませんか。
シャノンさんコメント有難う御座います。
そうなんですよね。何かが残っているのかとおもって、
追いかけていますが、未だに謎のままです。
CoCreateInstance を行っているのは一回で、
そこで得た インタフェースポインタをつかって、
Release()を実行しています。
戻り値は S_OK となっていますので、成功?とおもいきや、
タスクは残ったままのようです。
Release()にbreak をかけて、単発で実行してみました。
まずは、アプリAを終了せずに、アプリBからReleaseをかけてから、
アプリAを終了させると、無事に アプリAが落ちます。
今度は、アプリAを×印で終了させてから、アプリBからRelease を
かけても、アプリAのタスクは残ったままとなってしまいます。
いずれも Releaseの戻り値は S_OK となっています。
なんでしょうね・・・
終了イベントを捕まえないとNGなのでしょうかね。
頻繁にアプリAに問いかけるようになっていますが、
CoCreateInstance や Release を毎回実行する必要はないのですよね?
一番最初にCoCreateInstance を実行して、
何度もアプリAに問いかけたり、設定をしたりしています。
本当にもう使用しないときに、 Release を行っていますが、
あやまった使い方でしょうか?
>終了イベントを捕まえないとNGなのでしょうかね。
んなこたしません。
既にコメントがついているように、アプリBがアプリAを使っているのに、アプリAが勝手に終了してしまったら、もっと都合の悪いことになります。
アプリAをオートメーション起動した場合、アプリAに対して、通常はユーザ操作を許してはいけません。
Office アプリなんかは、オートメーション起動した場合デフォルトでアプリケーションウィンドウは非表示だったはずです。
オートメーション起動したアプリの終了方法は、アプリケーションごとに微妙に異なります。
Office 系のアプリについて言えば、
・Quit() メソッドを実行
・オートメーション起動に使用したアプリケーションのインターフェースポインタに対して Release() を実行
とするのがならわしです。
アプリAの正式な終了手順については、アプリAの資料を参照してください。
ただし、「正式な終了手順」を踏んでいたとしても、アプリAをオートメーションする上で使用したインターフェースポインタに1個でも Release() し忘れがあると、アプリAは終了しません。
>本当にもう使用しないときに、 Release を行っていますが、
>あやまった使い方でしょうか?
特に問題ありません。
> いずれも Releaseの戻り値は S_OK となっています。
Release の戻り値は HRESULT ではありませんが…
S_OK って中身は 0 でしたっけ。0 なら OK ですね。
> まずは、アプリAを終了せずに、アプリBからReleaseをかけてから、
> アプリAを終了させると、無事に アプリAが落ちます。
> 今度は、アプリAを×印で終了させてから、アプリBからRelease を
> かけても、アプリAのタスクは残ったままとなってしまいます。
この2つのケースで、アプリBには全く変更がなく、アプリAを先に終了させるかどうかの違いだけなら、アプリAのマニュアルを見るか、書いてなければ製作元に問い合わせた方がいいかもしれません。
ひどりさん、シャノンさん
コメント有難う御座います。
とても勉強になりました。
まずは、アプリAの使い方として、
アプリBから操作中でもアプリAの操作ができてしまう
作りになっているようです。
状態を監視する時などは、タイミングミスマッチが
おきることもありますよね。
そういうソフトウェアのようです。
色々しらべていったら、アプリAを操作するアプリが
複数あることも分かってきました。
それを平行して動作させている方もいるらしいです。
操作されるアプリAの中で矛盾しないのか、
操作しているアプリとしても、非常に疑わしい限りです。
とりあえず、アプリAにメッセージを送る前に、
CoCreateInstance や、CoGetInstance 等を行なうようにしました。
おわったら、即 Release すれば、今のところ大丈夫そうです。
既にアプリAが落ちている時に、CoCreateInstance を投げると、
アプリAが勝手に立ち上がってしまいますが、
どちらかというと、アプリAやアプリBは常時起動していて欲しい
システムで使用されるため、好都合となりました。
んー。本来の使い方では無いと思いますので、
アプリAの設計者にお尋ねしてみたいと思います。
とりあえず本件は、解決済みとさせて頂きたいと思います。
有難う御座いました。<m(__)m>
ツイート | ![]() |