基本的な事かもしれませんが、教えて下さい。
現在VB6で開発をしています。OSはXPです。
実現したいことは、2つのEXEを使用おり、
一方のEXE(仮にEXE:A)からもう一方(仮にEXE:B)をShellで起動させ、
起動が確認出来たらAのEXEを落としたいのですが、
どの様に判定したらいいかわかりません。
どなたか教えて下さい。よろしくお願いします。
Dim RetVal
RetVal = Shell("XXXXXXXXXXXXXX.EXE")
プログラムの実行に問題が発生した場合は、RetValに0が帰ってきます。
なので
if Shell("XXXX\B.EXE") <> 0 then unload me
で解決できるでしょうか?
少し私の説明不足な部分がありました。すみません。。
ムラタさんに教えて頂いた方法でも解決が出来なかったのですが、
どのような問題を解決したいかと言いますと、
呼び出したEXEが表示される前に呼び出しもとのEXEが
デスクトップ上より消えてしまい、一瞬の事ですが、
デスクトップが見えてしまう(どちらのEXEも表示されていない)
のを解決したいのです。。
これで解決できるでしょうか。
Shell "ProgramFile.exe",vbNormalFocus
書き方が悪かったので再度、
ムラタさんのコードと同じですが、
Shell関数に引数を追加しています。
If Shell("ProgramFile.exe",vbNormalFocus) <> 0 Then Unload Me
ナナさん了解です。
付け足してみました。
Dim RetVal
'フォーカスを持たずに起動させる。
RetVal = Shell("ProgramFile.exe", vbNormalNoFocus)
'正常起動時に、アクティブにする。
If RetVal <> 0 Then AppActivate RetVal: Unload Me
ちなみに、テストしてみて上手くいきました。
吉野さんの方法も試してみましたが、うまくいきませんでした。
以前VB5で開発されていたコードがあり、
Dim TIMEX, RcX, RcY As Long
RcX = Shell("ProgramFile.EXE " & PARM, 3)
TIMEX = Timer
RcY = FindWindow(vbNullString, "Form1")
Do While (RcY = 0 And Timer < TIMEX + 300)
RcY = FindWindow(vbNullString, "Form1")
Loop
このような形で書かれていたのですが、
これをそのままVB6にのせて使用すると、
EXE起動に時間がかかりすぎたり、固まってしまったりします。
どのように回避したらいいかわからず困っています。
ムラタさん。ごめんなさい。
入れ違いでカキコしてしまいました。
今から試してみます。
さっそくムラタさんの方法で試してみたのですが、
やはり両EXEとも消えてしまう瞬間があります。。
また、モジュールレベルで試すとうまくいっているのですが、
EXEで実行するとうまくいかないんです。。
同じEXEで他端末で試すとうまくいったのですが、
どうしてうまくいかないのか原因がわかりません((+_+))
グハッ><
そうですか〜
Unload Me 内でいろいろやってますか?
オブジェクトの開放くらいですが・・・
ムラタさんのコードに追加
Dim RetVal
'フォーカスを持たずに起動させる。
RetVal = Shell("ProgramFile.exe", vbNormalNoFocus)
'正常起動時に、アクティブにする。
If RetVal <> 0 Then AppActivate RetVal: DoEvents: Unload Me
^^^^^^^^^^
吉野さんありがとうございます。
試してみたのですが、
やはりうまくいきませんでした。。
FindWindowを使う方法も試しているのですが、
どちらの方法でもうまく解決出来ません((+_+))
実際に動かしていないので間違っているかもしれませんが、参考までに。
呼び出される側ExeのForm_Load若しくは、Form_Initializeに
処理時間がかかるような作業をしていませんか?
取りあえず、強制的に表示するようにしてみては如何でしょうか。
卑怯な手かもしれませんが…
呼び出される側Exe
Form_Load イベントに Me.Show を追加。(コードの一番上に追加します)
後は、これまでと同様、Shellを使って呼び出してみます。
呼び出し側Exe
Dim lngReturnCode As Long
lngReturnCode = Shell("ProgramFile.exe", vbNormalFocus)
If lngReturnCode <> 0 Then
Unload Me
End If
これでも表示されない場合は、
呼び出される側Exeの Me.Show の後に、
DoEvents 若しくは、Me.Refreshを追加してみてください。
もしBもプログラムできるなら、
AからBを立ち上げ、BからAを終了させるようにしたらどうでしょう。
AのフォームのKeyPreviewをTrueにしておき、
最新の一定文字数を常にバッファに入れるようにし、
バッファとキーワードが一致したらENDするようにプログラムしておく。
そしてBをノーマルフォーカス付で立ち上げる。
Bは立ち上がったら先ずshowで表示し、
AをAppActivateしてキーワードをSendkeysで送る。
実際にXP上でVB6で作成し、EXEファイルでテストしたところ、
上手くいきましたYO。
サイト復活したんですね☆
ブラックリストさんありがとうございます。
早速簡易EXEで試そうとしたのですが、
ロジックをうまく組むことが出来ませんでした。
A側とB側のサンプルコードを書いて頂けないでしょうか?
よろしくお願いしますm(__)m
こんな大げさなことをしてもいいなら
呼び出す側のプログラムは自分のハンドルを呼び出されるプログラムに渡す。
Dim s As String
Dim r
s = "B.exe" & " " & CStr(Me.hWnd)
r = Shell(s, 1)
呼び出されるプログラムは
Private Declare Function PostMessage Lib "user32" Alias _
"PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Const WM_CLOSE = &H10
Private Sub Form_Load()
Me.ZOrder 0
r = PostMessage(Val(Command), WM_CLOSE, 0, ByVal CLng(0))
End Sub
こんな方法も。
Project1にForm1とCommand1を準備してください。
Project2にForm2を準備してください。
それで、以下のコードをコピペしてください。
プロパティ等はなにも触らなくて良いです。
コンパイルして実行ファイルを同じフォルダにおけば動作します。
Project1のコード
Dim KeyBuf As String 'キーバッファ
Const txt = "END" '終了指定文字列なんでもかまいません
Const num = 3 '終了指定文字列の文字数
Private Sub Form_Load()
Form1.Caption = "Project1" 'キャプションを指定します。後でウィンドウの指定に使います。
Form1.KeyPreview = True '他のコントロールがあるなら、この指定をしてください。
Form1.Left = 0 '以下は特に必要ないけど、切り替えが上手くいってるのが見易い。
Form1.Top = 0
Form1.Width = Screen.Width
Form1.Height = Screen.Height
End Sub
Private Sub Form_KeyPress(KeyAscii As Integer)
KeyBuf = Right(KeyBuf + Chr$(KeyAscii), num) '押された最後のnum個の文字を保存する
If KeyBuf = txt Then End '文字列が終了文字列と同じなら終了
End Sub
Private Sub Command1_Click()
Shell "project2.exe", vbNormalFocus '二つ目のアプリを起動します。
End Sub
Project2のコード
Private Sub Form_Load()
Form2.Caption = "Project2" '分かり易いようにキャプションを変えました。
Form2.Left = 0 '見易いようにしました。
Form2.Top = 0
Form2.Width = Screen.Width
Form2.Height = Screen.Height
Me.Show 'フォームを表示します
AppActivate "Project1" '最初のウインドウのキャプションを指定します。
SendKeys "END" '終了指定文字を送ります。
End Sub
BからAを終了させるという考え方はねろさんも同じですね。
この場合は、APIを使った方がスマートですね。
SendKeyを使う方法は、終了だけでなくBからAを色々コントロールできるので、色々な応用ができます。参考になればいいね。
ツイート | ![]() |