アプリ版:「スタンプのみでお礼する」機能のリリースについて

VB6 SP5にて2重起動確実な防止処理をいれようとCreateMutex 関数を使用しようと思っています。
CreateMutex 関数を埋め込んでEXEを実行すると
実際に対象となるプログラムが起動しているにも関わらず起動してしまいます。

何がいけないのか?検討がつかず困っています。
下記がプログラムになります。
何かわかりましたらご回答の程、よろしくお願い致します。


***Win32API****************

Option Explicit

' CreateMutex 関数
Private Declare Function CreateMutex Lib "KERNEL32.DLL" Alias "CreateMutexA" ( _
ByRef lpMutexAttributes As Long, _
ByVal bInitialOwner As Long, _
ByVal lpName As String _
) As Long

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

SUB MAIN*********************************

Public Sub Main()
Dim hMutex As Long

hMutex = CreateMutex(ByVal 0&, 0&, App.Title)

On Error GoTo Err_Main

If Err.LastDllError = 0 Then
Dim cForm As Form1
Set cForm = New Form1

Call cForm.Show(vbModal)
End If

Err_Main:
If hMutex <> 0 Then
Call CloseHandle(hMutex)
End If
End Sub

************************************************

A 回答 (2件)

せっかく作ったミューテックスを獲得する


行為をしていません。つまり、何の制御も
していない状態です。
ミューテックスを獲得するには次のAPIを
使います。
Private Declare Function WaitForSingleOject _
  Lib "kernel32" (ByVal ハンドル As Long, _
  ByVal 待機時間 As Long) As Long
Const WAIT_TIMEOUT As Long = &H102

Dim 戻り値 As Long
戻り値 = WaitForSingleObject(hMutex, 0)
If 戻り値 = 0 Then
    '獲得成功
Else
    '獲得失敗(WAIT_TIMEOUTか-1)
End If
戻り値はタイムアウトなら他のプロセスで
ミューテックスを掴まれていることを示します。
ハンドルが無効ですと-1が返ります。

ミューテックスは争奪するもので、唯一つの
ミューテックスを勝ち得たものだけが制御権を
得るのですが、それはそのようにプログラム
しなければいけないと言うことです。獲得でき
ないのに処理を進めてしまったり、用が済んだ
のに解放しないとかはプログラマの責任です。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
補足なのですが
CreateMutexで生成する際、生成エラーで(Err.LastDllError)でエラーコードが入ると思っていましたがエラーになりませんでした。

回答いただきたWaitForSingleObjectを試してみたのですが
戻り値 = WaitForSingleObject(hMutex, 0)
プログラムが起動していても戻り値が0になります。
不慣れなもので何がおかしいのかわからない状況です。

(変更プログラム)
Sub main()
Dim hMutex As Long
Dim ErrCode As Long


Dim LWaitFor As Long

' 新しい Mutex を生成する (Mutex の名前にプロジェクト名を付ける)
hMutex = CreateMutex(ByVal 0&, 0&, App.Title)

' 実行時エラーが発生した場合は Finally ラベルに制御を移す (Mutex へのハンドルを確実に閉じるため)
On Error GoTo Finally
''' ErrCode = err.LastDllError

LWaitFor = WaitForSingleObject(hMutex, 0)

If LWaitFor = 0 Then
Comm.Show
End If


Finally:
' Mutex へのハンドルを閉じる
If hMutex <> 0 Then
Call CloseHandle(hMutex)
End If
End Sub

お礼日時:2012/03/29 16:31

>プログラムが起動していても戻り値が0になります。


正しくプログラムしていれば絶対にありません。
最初に起動したプログラムは最後までミューテックスを
保持してますか?

正常時のShowメソッドがモーダルになっていないので、
そのままFinallyへ流れてミューテックスを閉じている
ような気がします。閉じてしまってはミューテックスを
手放したのと同じですから、後続のプロセスは問題なく
ミューテックスを捕まえることができ、処理を続行します。
    • good
    • 0
この回答へのお礼

ありがとうございました。

うまく行きました。
デバッグにて最初の起動させていたプログラムにミューテックスの処理が
入っていなかった為、戻り値が0となっていました。(すみません。あせっていたもので!)

助かりました。

お礼日時:2012/04/02 14:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!