- ベストアンサー
VB6.0 SHELLで起動したプログラムを終了さしたいのですが
(1)メインプログラムから電卓を実行します。 Shell("C:\WINNT\system32\CALC.EXE", 1) (2)メインプログラムで電卓を終了させるにわ、どうすればいいのですか 教えてください。
- chiba-masaru
- お礼率23% (40/169)
- Visual Basic
- 回答数5
- ありがとう数9
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
(今会社なのですが、、、)サンプルありました。奥深く眠ってました。 Microsoftの終了方法と、定数が違いますが、こちらでも終了ができます。 コメントを見たら、処理の流れがわかると思いますが、処理の流れを記します。 Shellで電卓を起動します。Shell関数は起動したアプリのプロセスIDを返します。 次に Call EnumWindows(AddressOf EnumWinProc, 0&)を実行します。 これはたった一文で、FOR文/DO~LOOP文を使用してませんが、EnumWinProc関数内を何度も実行します。実行回数はWindowsに存在するハンドルの数だけ実行されます。 そしてその関数内で電卓のプロセスと同じハンドルを探し、電卓に終了の命令を送ってます。 EnumWinProc内を詳しく説明します。 GetParentが'0'ゼロの時、未処理としています。 これは何を意味するかというと、フォームだけでなく、フォームの中に存在するボタン、リストボックス、ラベル、それぞれのコントロールにハンドルが存在します。 しかしフォームとその中のコントロールには親子の関係があります。 GetParent(子のハンドル)の時 → '0以外'の数値を返します。基本的にフォーム(親)のハンドルのを返します。 GetParent(フォームのハンドル)の時 → '0'を返します。親が存在しないためです。 電卓にも多くのボタンが存在してます。そのボタンのハンドルはチェックする必要がないのでGoto文で未処理にさせています。必要なのは電卓本体が必要で、GetParentで0を返すものが、チェックの候補となるわけです。 あとは電卓のプロセスと比較し、一致するハンドルを取得するだけです。 Option Explicit ' ウィンドウのプロセスIDとスレッドIDを取得する関数の宣言 Private Declare Function GetWindowThreadProcessId Lib "user32.dll" _ (ByVal hwnd As Long, lpdwProcessId As Long) As Long '親ハンドルを取得する関数の宣言 Private Declare Function GetParent Lib "user32" _ (ByVal hwnd As Long) As Long 'ウィンドウを列挙する関数の宣言 Public Declare Function EnumWindows Lib "user32" _ (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long 'ウィンドウにメッセージ定数を送る関数の宣言 Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long Public Const WM_CLOSE = &H10 '見つかったウィンドウハンドル Private FindWinWnd As Long '探すべきプロセス Private FindPrs As Long Sub Main() Dim lngSts As Long '初期化を行う FindWinWnd = 0 FindPrs = 0 'とりあえず電卓を起動と同時に、電卓のプロセスを得る FindPrs = Shell("Calc.exe") 'プロセス=0のとき起動失敗 If FindPrs = 0 Then MsgBox "電卓の起動失敗" GoTo PGMEND End If 'Windowsに存在する全部のハンドルから、電卓のプロセスの一緒のハンドルを探す Call EnumWindows(AddressOf EnumWinProc, 0&) '電卓を終了します。 If (FindWinWnd <> 0&) Then MsgBox "電卓が見つかりませた。終了します。" Call SendMessage(FindWinWnd, WM_CLOSE, 0&, 0&) Else MsgBox "電卓が見つかりませんでした。" End If PGMEND: End Sub 'Windowsの全ハンドルを得ることができる関数 '内部処理は、 '(1)指定のプロセスを探す '(2)見つかったプロセスのハンドルを記憶 Public Function EnumWinProc(ByVal hwnd As Long, lParam As Long) As Boolean Dim lngTrd As Long 'スレッド Dim lngPrs As Long 'プロセス 'Trueの間は、Windowsに存在するハンドルを最後まで取得しようとする EnumWinProc = True '子ウィンドウは未処理 If Not (GetParent(ByVal hwnd) = 0) Then GoTo PGMEND 'スレッドとプロセスを取得する lngTrd = GetWindowThreadProcessId(hwnd, lngPrs) '同じプロセスだとしたら If lngPrs = FindPrs Then '取得してきたハンドルを記憶 FindWinWnd = hwnd 'これ以上のハンドルは取得しないでもいいので、Falseをセット EnumWinProc = False End If PGMEND: End Function
その他の回答 (4)
- TAGOSAKU7
- ベストアンサー率65% (276/422)
あっSendMessageの回答がでましたね。 で注意して欲しいのは、FindWindowを使う点です。 これはWindowのCaption、もしくはクラス名でWindowを探す点です。 クラス名は[CTRL]+[ALT]+[DEL]で起動中のアプリのクラス名の一覧が出てきます。 あれから参考にしてみてください。 電卓は複数起動が可能です。 Microsoftのサンプルでは、すでに電卓を起動してあったとき、先に起動してあったほうを終了させるおそれがあります。 よってFindWindowだけでWindowを探すには注意が必要です。 (それでもSendkeysよりは、かなりいいと思います。) もし自分で作成したソフトをShellで起動するなら、このままでも大丈夫かもしれませんが、そうでなければShellで起動した時のプロセスIDを取得して、起動中のアプリ達のプロセスIDと比較し、自分の起動したEXEかをチェックする必要があるのです。 今までのサンプルで大丈夫ならいいのですが、帰ってから締め切ってなかったら、またあとで書き込みます。 ちなみに書き込もうとしてるサンプルはVB6限定です。
お礼
ありがとうございました、いちどためさしていただきます。 また何かありましたらよろしくお願いします。
- todo36
- ベストアンサー率58% (728/1234)
API関数を使うなら...
- TAGOSAKU7
- ベストアンサー率65% (276/422)
Sendkeys は一番手っ取り早いです。 確かにHELPにも出ています。 しかし、どのVBのメーリングリストもSendkeysは使用しない方向でやっております。 それはWindowsにかかっている負荷の状況により、Sendkeysの処理が必ずしも一致するわけではないからです。 以前にサンプルを作ったのですが、どうやら自宅においたままになっているようなので、またあとで書き込みます。 キーワードはSendMessageです。
- bin-chan
- ベストアンサー率33% (1403/4213)
SendKeyで終了のキー操作情報を送信してやります。 たしかHELPのサンプルが電卓を終了させるものだったと記憶しています。
関連するQ&A
- WSHプログラミングで、Shell実行プロセスが終了しない内に、次の処理が実行されちゃいます・・・
WSH(WindowsScriptingHost)でプログラミングを行っております。 以下のように、「A.exe」実行後、「B.exe」を実行するようにスクリプトを記述しています。 ところが、実際に実行してみると、「A.exe」が終了しない内に、「B.exe」が実行されてしまっている様なのです。 しかし、プログラム処理上、「A.exe」が実行終了してからでないと、「B.exe」を実行するのはまずいのです。 WSHで、「A.exe」が実行終了するまで、「B.exe」を実行させないようなスクリプトの記述方法を教えて下さい。 Set Shell = CreateObject("WScript.Shell") Shell.Run "cmd.exe /c D:\A.exe" Shell.Run "cmd.exe /c D:\B.exe"
- ベストアンサー
- その他(プログラミング・開発)
- VBで別のプログラムを起動し他の処理を中断したい
VBプログラムの実行中に、shell("hoge.exe")で別のプログラムを起動しそのプログラムが終了すれば次の処理に移るという処理をしたいんですが、実現方法がわかりません。どうすればよいでしょうか?アドバイスよろしくお願いします。
- ベストアンサー
- Visual Basic
- VBAのShellの同期的実行
ExcelVBAについての質問です。コマンドプロンプトで実行するプログラムをCで作成しました(これをXXX.exeとします)。このプログラムは計算が終了した後で、その結果のファイルを作成します(これをYYY.txtとします)。このプログラムを操作し、結果を表にして出力するために、ExcelVBAでshellを使って以下のようなプログラムを作成しました。 shell("XXX.exe") call Output Outputでは、XXX.exeが作成したファイルYYY.txtからデータを読み込んでシートに結果を出力するのですが、うまくファイルを読み込みません。多分、shellにより実行したXXX.exeが終了する前にOutputが呼ばれているのだと思うのですが、もしそうだとしたらどのような解決方法があるのでしょうか。よろしくお願いします。 WinXp、Excel2000です
- ベストアンサー
- オフィス系ソフト
- VB6のWScript.Shellについて
VB6のWScript.Shellで、他のVB6プログラムを起動する時の戻り値について教えてください。 AというVBプログラムからBというVBプログラムを起動するシステムがあります。 Bというプログラムで取得した値をAに返す方法はありますでしょうか? Aのソースは以下の通りです。 --------------------------------------------- sub test() dim objWshShell set objWshShell = Wscript.CreateObject("WScript.Shell") objWshShell.Run "C:\B.exe" & " " & hikisu1 & " " & hikisu2 , 1, wait End Function ---------------------------------------------- objWshShell.Runの戻り値はtrueまたはfalseのみのようです。 B.exeからtrue、false以外の値を取得する方法はありますか? また、やり方はobjWshShell.Runでなくてもよいです。 よろしくお願いします。
- ベストアンサー
- Visual Basic
- Shell関数で起動したメディアプレーヤーを終了したい。
以前このコーナーで質問して教えて頂いたShell関数でメディアプレーヤーを起動できました。(以下にそのコーディングを記載しました) 今度は起動したメディアプレーヤーをVBから終了する方法が知りたいのですが教えて頂けませんか。 Shell ("C:\Program Files\Windows Media Player\wmplayer.exe /1 G:\TEST.wma ,vbMinimizedFocus") 宜しくお願いします。
- ベストアンサー
- Visual Basic
- VBプログラムの終了
VB6.0で作成した実行ファイル(exe)を終了させても タスクマネージャのプロセスに残ってしまい、 もう一度プログラムを起動することができません。 (プログラムで二重起動防止の処理をしています) このプログラムをVBのラインタイムが入っていない マシンで動かしているのですが、 やはりそれが問題なのでしょうか? それとも別に何か原因があるのでしょうか?
- ベストアンサー
- Visual Basic
- Access2000vbaで、shell関数で起動させたExcellを終了する方法を教えてください。
Access2000vbaで、shell関数で起動させたExcellを終了する方法を教えてください。 以下のように、shell関数で、既存のExcelファイルを起動させました。 どうすれば、Excelファイルを終了できますか? 宜しくお願いします。 Dim fl_name As String fl_name = "C:\XE2.xls" Shell "C:\Program Files\Microsoft Office\Office\EXCEL.EXE " & fl_name, vbNormalFocus
- ベストアンサー
- Visual Basic
- Shell とcmd.exe /c start
Shell "cmd.exe /c start " & Label1.Caption ラベルにURLを設定し、クリックした時にURLに飛ぶとあります。 コードの理解が難しく、お助け頂けませんか。 プログラミングもPCもド素人ですのでご了承下さい。。。 Shell:実行可能なプログラム(この場合ならcmd.exe?)を実行し、実行が完了するとプログラムのタスクIDを示す(このタスクidでプログラムを操作することになるのだろうか?)。 cmd.exe:コマンドプロンプト cmd.exe/c:コマンドプロンプトで特定のコマンド(URL先へ飛ぶ?)を実行後に終了させる? Label1.Caption:ラベルの内容(URL) startがわからない。何をstartするためのstart? cmd.exeのstart(起動)をShellが実行して、URL先に飛ぶ命令は残りのコードにある? 参照ページでも歓迎です。宜しくお願いします。
- ベストアンサー
- Visual Basic
- VB6.0 Shellによる終了監視について
VB6.0について困っております。 VB6.0にてファイル管理ソフトを開発しています。VBより他アプリ(MS OfficeやAutoCAD等)ファイルを起動させ、終了を監視(終了処理実行のため)しています。 具体的にはWshのshell.Runコマンドを使用して wsh.run("アプリ",NormalFocus,True)として起動させています。 ここで、複数ファイルを起動した場合、最後に起動したファイルが終了しないと、他の終了が検知できません。 例) ファイルAを起動 ファイルBを起動 ファイルCを起動 ファイルDを起動 ↓ ファイルAを終了 ←終了しても終了検知しない ファイルBを終了 ←終了しても終了検知しない ファイルCを終了 ←終了しても終了検知しない ファイルDを終了 ←終了するとA・B・C・Dの終了をまとめて検知し終了処理実行 これを、各ファイルごとに終了を検知させる方法はありませんでしょうか? よろしくお願い致します。
- 締切済み
- Visual Basic
お礼
ありがとうございました、いちどためさしていただきます。 また何かありましたらよろしくお願いします。