OSWin98/VB5.0を使用しています。同一のシステムの重複起動を防止したいのです。過去ログの、
http://oshiete1.goo.ne.jp/kotaeru.php3?q=644390
を参照し、
http://www.vbvbvb.com/jp/gtips/1101/gCreateToolh …
のサンプルを参考にし、実行中のプロセスに同一のものがあれば、複数起動と判断するようにしました。
しかし、どうしても二重起動されてしまいます。
例1)A.exeを起動、A.vbpをデバッグで実行
→二重起動を検出し、後者は起動されない
例2)A.exeを起動、A.exeを起動
→二重起動が検出されず、後者も起動されてしまう
App.PrevInstanceで判断できると思うのですが、例1と同じ方法でもこの場合は、二重起動を防ぐことができません。
他によい方法がある、ここがおかしいんじゃないの?等ありましたら、教えてください。
よろしくお願いします。
No.2ベストアンサー
- 回答日時:
> それでも二重起動ができてしまう
Sub Main() が実行されていないのでは?
MsgBoxを表示させる等、工夫して、必要な処理が間違いなく実行されているか確認してください。
尚、App.PrevInstanceプロパティで防止できる二重起動は文字通り同一の実行ファイルの場合のみです。同じEXEファイルでも、コピーして複数のフォルダに配置すれば二重起動は可能です。
Mutexを使用する方法であれば、上記のケース (別の場所に同一プログラムが複数存在)でも起動できるのは1つだけです。
[コード例]
Option Explicit
' 指定されたクラス名とウィンドウ名を持つトップレベルウィンドウを探す。
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
' 指定されたウィンドウが所有するポップアップウィンドウのうち、
' 直前にアクティブであったウィンドウを調べる。
Private Declare Function GetLastActivePopup Lib "user32" _
(ByVal hWndOwnder As Long) As Long
' 指定されたウィンドウを作成したスレッドをフォアグラウンドにし、そのウィンドウをアクティブにする。
Private Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
' 指定されたウィンドウの表示状態を設定する。
Private Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal nCmdShow As Long) As Long
Private Const SW_RESTORE = 9
Private Declare Function OpenMutex Lib "Kernel32" Alias "OpenMutexA" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal lpName As String) As Long
Private Declare Function CreateMutex Lib "Kernel32" Alias "CreateMutexA" _
(ByVal lpMutexAttributes As Long, _
ByVal bInitialOwner As Long, _
ByVal lpName As String) As Long
Private Declare Function ReleaseMutex Lib "Kernel32" (ByVal hMutex As Long) As Long
Private Declare Function CloseHandle Lib "Kernel32" (ByVal hObject As Long) As Long
Private Const SYNCHRONIZE As Long = &H100000
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000
Private Const MUTEX_QUERY_STATE As Long = &H1
Private Const MUTEX_ALL_ACCESS As Long = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or MUTEX_QUERY_STATE
'ミューテックスオブジェクトのハンドル
Private hMutex As Long
'メインフォームのキャプション
Public Const pCstStrAppTitle = "Mutexによる重複起動防止"
Public Sub Main()
Dim strAppCaption As String
Dim lngFirstTophWnd As Long
Dim lngFirstPophWnd As Long
Dim lngResult As Long
'実行ファイルの場合のみ重複起動防止処理を行う。
If IsExeFile Then
If IsMutexEntity(pCstStrAppTitle) Then
' 多重起動を許さない。
' アプリケーションのキャプションを得る。
strAppCaption = App.Title
' 自アプリのキャプションを変更しておく。
App.Title = strAppCaption & Space(1)
' トップレベルのウィンドウハンドルを得る。
lngFirstTophWnd = FindWindow("ThunderRT6Main", strAppCaption)
' ちなみに、Visual Basic 5アプリの場合。
'lngFirstTophWnd = FindWindow("ThunderRT5Main", strAppCaption)
' 直前にアクティブなウィンドウハンドルを得る。
lngFirstPophWnd = GetLastActivePopup(lngFirstTophWnd)
' ウィンドウをアクティブにする。
lngResult = SetForegroundWindow(lngFirstPophWnd)
' 最小化されタスクバーに格納されてある場合があるので、ウィンドウを通常表示にさせる。
lngResult = ShowWindow(lngFirstPophWnd, SW_RESTORE)
' アプリケーションを終了させる。
End
End If
End If
frmMain.Caption = pCstStrAppTitle
frmMain.Show
End Sub
Public Function IsMutexEntity(ByRef strAppTitle As String) As Boolean
'Mutexが作成されているか調べる。作成されていなかったら作成する。
Dim strBuff As String
strBuff = String(255, 0)
Mid$(strBuff, 1, Len(strAppTitle)) = strAppTitle
'Mutexを開く。
hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, strBuff)
'Mutexオブジェクトがすでに存在する場合はハンドルをクローズし、終了。
If hMutex <> 0 Then
Call CloseHandle(hMutex)
IsMutexEntity = True
Exit Function
End If
'ミューテックスオブジェクトを作成する。
hMutex = CreateMutex(0, 0, strBuff)
End Function
Public Sub TerminateMutex()
'Mutexオブジェクトを解放する
Call ReleaseMutex(hMutex)
End Sub
Public Function IsExeFile() As Boolean
'実行ファイルか、IDE上の実行かを判定する。
On Error Resume Next
Debug.Print 1 / 0
IsExeFile = CBool(Err.Number = 0)
On Error GoTo 0
End Function
すみません。
私が大ボケでした。(二重起動を許可するかコマンドラインから引数を取得するところがうまくいっていませんでした。なので、二重起動チェックが起動していなかったのです。)
教えていただいたとおりにやってみるとできました。今日は一日はまっていたので、本当に助かりました。
本当に本当にありがとうございました。
No.1
- 回答日時:
App.PrevInstanceプロパティを利用する方法は下記の通りです。
(一例)' 指定されたクラス名とウィンドウ名を持つトップレベルウィンドウを探す。
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
' 指定されたウィンドウが所有するポップアップウィンドウのうち、
' 直前にアクティブであったウィンドウを調べる。
Private Declare Function GetLastActivePopup Lib "user32" _
(ByVal hWndOwnder As Long) As Long
' 指定されたウィンドウを作成したスレッドをフォアグラウンドにし、そのウィンドウをアクティブにする。
Private Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
' 指定されたウィンドウの表示状態を設定する。
Private Declare Function ShowWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal nCmdShow As Long) As Long
Private Const SW_RESTORE = 9
Public Sub Main()
Dim strAppCaption As String
Dim lngFirstTophWnd As Long
Dim lngFirstPophWnd As Long
Dim lngResult As Long
If App.PrevInstance Then
' 多重起動の禁止。
' アプリケーションのキャプションを得る。
strAppCaption = App.Title
' 自アプリのキャプションを変更する。
App.Title = strAppCaption & " "
' トップレベルのウィンドウハンドルを得る。
lngFirstTophWnd = FindWindow("ThunderRT5Main", strAppCaption)
' Visual Basic 6.0アプリの場合。
'lngFirstTophWnd = FindWindow("ThunderRT6Main", strAppCaption)
' 直前にアクティブなウィンドウハンドルを得る。
lngFirstPophWnd = GetLastActivePopup(lngFirstTophWnd)
' ウィンドウをアクティブにする。
lngResult = SetForegroundWindow(lngFirstPophWnd)
' 最小化されタスクバーに格納されてある場合があるので、ウィンドウを通常表示にさせる。
lngResult = ShowWindow(lngFirstPophWnd, SW_RESTORE)
' アプリケーションを終了させる。
End
End If
End Sub
ただし、.NETでは、このコードは使用できません。
VB以外の開発ツールでは、Mutex等を使用する方法が一般的なようです。
http://dobon.net/vb/dotnet/process/checkprevinst …
参考URL:http://dobon.net/vb/dotnet/process/checkprevinst …
この回答への補足
ありがとうございます。教えていただいたとおりにやっているのに、それでも二重起動ができてしまうとしたら、何か考えられる問題があるでしょうか。お心あたりがありましたら教えてください。
補足日時:2003/12/11 17:33お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
作成したウインドウのサイズを...
-
「アイテムは収集されました」...
-
勝手にウィンドウが開いて止ま...
-
ウィンドウのサイズ変更について
-
カーソルが自分のウィンドウか...
-
ゲームでは結局どっちが良いの?
-
Excelの上下を固定したい
-
c++/cli .NET Formアプリケー...
-
VBAで単一ブック複数窓を閉じる...
-
他のアプリケーションの終了処理
-
ExcelのBOOKが消えた!
-
[VBA] UserForm を Excel の W...
-
エクセルの一行目を固定して見...
-
検索の画面がでなくなってしま...
-
他アプリの操作(メニューバー)
-
WM_PAINT 処理が完了したタイミ...
-
C言語でWin32APIを使い、子ウィ...
-
最大化時のフルスクリーン
-
【VB2008】 マウス操作の一時的...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
勝手にウィンドウが開いて止ま...
-
ゲームでは結局どっちが良いの?
-
検索の画面がでなくなってしま...
-
VBA .Value=.Value ?
-
Excelの上下を固定したい
-
ExcelのBOOKが消えた!
-
他のアプリケーションの終了処理
-
Vba LongPtrについて教えてくだ...
-
「&HFFFF」「&H1A」とは?
-
MFC ダイアログ上のID取得につ...
-
作成したウインドウのサイズを...
-
[VBA] UserForm を Excel の W...
-
ラジオボタンの初期指定
-
【VB2008】 マウス操作の一時的...
-
ExcelVBAでAPIを使って外部ウイ...
-
VBAで単一ブック複数窓を閉じる...
-
EnumChildWindowsの使い方(VBA)
-
隠れたウィンドウの画面をキャ...
おすすめ情報