tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトル外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15659
投稿日: 2013/04/04(Thu) 15:51
投稿者e=mc2
マウスを制御する外部アプリーケーションを起動して、プログラム終了時に強制終了させていますが、このアプリケーションがタスクバーに常駐型で、終了はするのですが、アイコンが残ったままとなってしまいます。マウスをタスクバーに持っていくとアイコンが消えますが、そのままにしていると起動するたびにアイコンが増えていきます。タスクバーのアイコンを消す方法をお教えいただけないでしょうか。

使用しているサンプルソースです。

-------------------------------------------------------------------------------
'標準モジュール

Option Explicit

' OpenProcess 関数
Public Declare Function OpenProcess Lib "KERNEL32.DLL" ( _
    ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle  As Long, _
    ByVal dwProcessId     As Long  _
) As Long

' CloseHandle 関数
Public Declare Function CloseHandle Lib "KERNEL32.DLL" ( _
    ByVal hObject As Long _
) As Long

' TerminateProcess 関数
Public Declare Function TerminateProcess Lib "KERNEL32.DLL" ( _
    ByVal hProcess  As Long, _
    ByVal uExitCode As Long  _
) As Long

' 定数の定義
Public Const SYNCHRONIZE       As Long = &H100000
Public Const PROCESS_TERMINATE As Long = &H1

-------------------------------------------------------------------------------
アプリ起動:

'test.exeを起動して、プロセス ID を取得する
Dim lProcessId As Long
lProcessId = CLng(Shell("test.exe", vbNormalFocus))

' プロセスのハンドルを取得する
Dim hProcessHandle As Long
hProcessHandle = OpenProcess(SYNCHRONIZE Or PROCESS_TERMINATE, 0&, lProcessId)

-------------------------------------------------------------------------------
プログラム終了時:

'test.exeを強制終了する
Call TerminateProcess(hProcessHandle, 0&)

'プロセスのハンドルを閉じる
Call CloseHandle(hProcessHandle)

-------------------------------------------------------------------------------

以上です。
どうぞよろしくお願いいたします。

[ツリー表示へ]
タイトルRe: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15660
投稿日: 2013/04/05(Fri) 01:28
投稿者VBレスキュー(花ちゃん)
プロセスを強制終了するような方法では、アイコンが消えないようです。
WMI の Process.Terminate も同様です。
.NET 系の Process.CloseMainWindow() で終了させるなら簡単で消えるのですが
VB6.0 となると タスク ID から Window のハンドルを取得して、SendMessage で
WM_CLOSE を送ってやるとアイコンが消えます。(しかしながら結構面倒くさい)
(正常に終了させないとアイコンが残ります。)
他にもっと簡単な方法があるかも知れませんが、ちょっと思いつきません。

そもそも常駐ソフトを頻繁に強制終了しなければならないような仕様は見直した方が無難かと
思いますが。

[ツリー表示へ]
タイトルRe^2: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15663
投稿日: 2013/04/05(Fri) 13:33
投稿者e=mc2
> プロセスを強制終了するような方法では、アイコンが消えないようです。
> WMI の Process.Terminate も同様です。
> .NET 系の Process.CloseMainWindow() で終了させるなら簡単で消えるのですが
> VB6.0 となると タスク ID から Window のハンドルを取得して、SendMessage で
> WM_CLOSE を送ってやるとアイコンが消えます。(しかしながら結構面倒くさい)
> (正常に終了させないとアイコンが残ります。)
> 他にもっと簡単な方法があるかも知れませんが、ちょっと思いつきません。
>
> そもそも常駐ソフトを頻繁に強制終了しなければならないような仕様は見直した方が無難かと
> 思いますが。

VBレスキュー(花ちゃん) 様
ご返信有難うございます。

そうですか。。。結構面倒なのですね。

常駐ソフトを起動するのはVBプログラムの起動時(一日一回程度)なので
そんなに問題ではないのですが、気持ち的にアイコンを消したいなぁと
思っておりまして。

少々複雑でもお教えいただく事はご無理を申し上げることになりますでしょうか。
タスク ID や SendMessage などで検索してみましたが使い方がわかりませんでした。
勉強不足で申し訳ございません。

ご検討くださいませ。

[ツリー表示へ]
タイトルRe^3: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15664
投稿日: 2013/04/05(Fri) 14:04
投稿者魔界の仮面弁士
>> プロセスを強制終了するような方法では、アイコンが消えないようです。

もしかしたら、TaskKill コマンドなら消えるかも。
少なくとも、当方の OneNote2010 や秀丸については消えました。(Windows 7 Enterprise/64bit)

Private Sub Command1_Click()
    Shell "TaskKill.exe /IM OneNoteM.exe", vbHide
End Sub


> 少々複雑でもお教えいただく事はご無理を申し上げることになりますでしょうか。
.NET からなら Process.CloseMainWindow() で簡単に消せるとのことなので、
環境が許すなら、PowerShell でスクリプトを組むのも手かと思います。
VB6 から呼びたいなら、Shell 関数経由で実行させても良いですし。

[ツリー表示へ]
タイトルRe^4: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15665
投稿日: 2013/04/05(Fri) 16:17
投稿者VBレスキュー(花ちゃん)
VB6.0 で作成したものもVB2010 で作成した常駐のソフト両方で消える事が確認できました。
Windows 7 32bit

対象ファイルをフルパスで指定したらだめなのですね。
taskkill.exe が入っていない環境もあるようですね。

テストしてみたところでは、強制終了ではなさそうですね、QueryUnload イベントで
vbAppTaskManager が取得できているので。

[ツリー表示へ]
タイトルRe^5: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15670
投稿日: 2013/04/06(Sat) 16:09
投稿者魔界の仮面弁士
> 対象ファイルをフルパスで指定したらだめなのですね。
あくまでイメージ名なので、 Win32_Process.Name 相当の指定になりますね。

パスの違う別ファイルがある場合は、/FI オプションでウィンドウタイトルで絞り込むか、
あるいは /PID オプションでプロセスを特定すると良いでしょう。

PID については、WMI の Win32_Process から ExecutablePath で探索して、
ProcessId プロパティから得ることができます。あるいは Shell 関数で
起動しているなら、その戻り値をそのまま使えるかと思います。


> taskkill.exe が入っていない環境もあるようですね。
Windows 2000 以下の世代だとありませんね。
XP Pro 以降にはありますが、XP Home や XP MCE にはありません。


> テストしてみたところでは、強制終了ではなさそうですね、
強制終了は /F オプションです。通常は先の CloseMainWindow メソッドや
EndTask API と同様に、最上位ウィンドウに対する WM_CLOSE だったはず。

[ツリー表示へ]
タイトルRe^6: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15671
投稿日: 2013/04/06(Sat) 18:03
投稿者VBレスキュー(花ちゃん)

> 強制終了は /F オプションです。通常は先の CloseMainWindow メソッドや
> EndTask API と同様に、最上位ウィンドウに対する WM_CLOSE だったはず。

ありがとうございます。
オプション設定が色々できるようですね。
taskkill.exe って、私のサイトで名前がでてきたのがはじめてだったので少し調べた
だけだったので今度ゆっくり試して見たいと思います。

[ツリー表示へ]
タイトルRe^4: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15667
投稿日: 2013/04/05(Fri) 16:58
投稿者e=mc2
> >> プロセスを強制終了するような方法では、アイコンが消えないようです。
>
> もしかしたら、TaskKill コマンドなら消えるかも。
> 少なくとも、当方の OneNote2010 や秀丸については消えました。(Windows 7 Enterprise/64bit)
>
> Private Sub Command1_Click()
>     Shell "TaskKill.exe /IM OneNoteM.exe", vbHide
> End Sub
>
>
> > 少々複雑でもお教えいただく事はご無理を申し上げることになりますでしょうか。
> .NET からなら Process.CloseMainWindow() で簡単に消せるとのことなので、
> 環境が許すなら、PowerShell でスクリプトを組むのも手かと思います。
> VB6 から呼びたいなら、Shell 関数経由で実行させても良いですし。

環境をお伝えしていませんでした。申し訳ございません。

Windows7 64bit Vb6.0 SP6B

です。

QueryUnloadイベントでプロセスを強制終了している最後の部分をコメント化して、
TaskKill.exeを書き足しましたが終了しませんでした。書き方が悪いのでしょうか。。。

--------------------------------------------------------------------------------
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

'強制終了する
'Call TerminateProcess(hProcessHandle, 0&)
    
'プロセスのハンドルを閉じる
'Call CloseHandle(hProcessHandle)
    
Shell "TaskKill.exe /IM test.EXE", vbHide

[ツリー表示へ]
タイトルRe^5: 外部のアプリを起動して終了させてもタスクバーのアイコンが消えない
記事No15668
投稿日: 2013/04/05(Fri) 17:54
投稿者VBレスキュー(花ちゃん)
> TaskKill.exeを書き足しましたが終了しませんでした。書き方が悪いのでしょうか。。。

その常駐ソフトの終了処理の部分(Form_Unload イベント内)はどのように書かれています。
Shell_NotifyIcon(NIM_DELETE, pnid) のような処理がなされていますか?

TaskKill.exe で QueryUnload イベントが発生しているので終了処理がきちんと書かれていれば
アイコンが消えるはずですが。

[ツリー表示へ]