DOBON.NET DOBON.NETプログラミング掲示板過去ログ

プログラムの二重起動について

環境/言語:[VB.NET]
分類:[.NET]

VB.NETでプログラムを開発しており、プログラムの二重起動で苦戦致しております。

当掲示板に掲載がありました、

Function PrevInstance() As Boolean
If UBound(Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName)) > 0 Then
Return True
Else
Return False
End If
End Function
で二重起動は防止できるのですが、同じプロブラムIDのプログラムを
(例)
 C:\TEST\test.exe
C:\TEST1\test.exe
 と同一端末内の複数箇所にセットした場合、上記処理では全ての処理が起動不可となります。

Process.GetCurrentProcess.MainModule.FileNameで起動場所(C:\TEST\test.exe)は取得できるのですが、判断方法が分かりません。

どなたかご存知ないでしょうか?
■No18799に返信(よしさんの記事)
> VB.NETでプログラムを開発しており、プログラムの二重起動で苦戦致しております。
>
> 当掲示板に掲載がありました、
>
> Function PrevInstance() As Boolean
> If UBound(Diagnostics.Process.GetProcessesByName(Diagnostics.Process.GetCurrentProcess.ProcessName)) > 0 Then
> Return True
> Else
> Return False
> End If
> End Function
> で二重起動は防止できるのですが、同じプロブラムIDのプログラムを
> (例)
>  C:\TEST\test.exe
> C:\TEST1\test.exe
>  と同一端末内の複数箇所にセットした場合、上記処理では全ての処理が起動不可となります。
>
> Process.GetCurrentProcess.MainModule.FileNameで起動場所(C:\TEST\test.exe)は取得できるのですが、判断方法が分かりません。
>
> どなたかご存知ないでしょうか?

二重起動を防止したいの?それともプロセスIDを取得したいの?私の理解力が低いので申し訳ないのですが、
二重起動を確実に禁止するサンプルなら、じゃんぬさんのサイトにあります。
http://jeanne.wankuma.com/tips/process/mutex.html
■No18800に返信(ぺがらぼさんの記事)
> 二重起動を防止したいの?それともプロセスIDを取得したいの?私の理解力が低いので申し訳ないのですが、
> 二重起動を確実に禁止するサンプルなら、じゃんぬさんのサイトにあります。
> http://jeanne.wankuma.com/tips/process/mutex.html
>
説明が不足しており申し訳ございません。

(例)
 1.C:\TEST\test.exe
2.C:\TEST1\test.exe
と同一端末内の複数箇所にセットした場合で、1.C:\TEST\test.exeが既に起動されている場合
 A.C:\TEST\test.exeは起動出来ない。
B.C:\TEST1\test.exeは起動出来る。
ように判断したいのです。

もともとVB6のApp.PrevInstanceと同じ結果を取得したいのです。
■No18802に返信(よしさんの記事)

リンク先(じゃんぬさんの説明)を読まれていますか?

というか、Mutex の名前はそれぞれ自分で設定できるわけで、じゃんぬさんのサンプルでは
Application.ProductName を使っているけれど、それを Application.ExecutablePath を使うよう
にすればいいだけなのだと思いますが。
■No18803に返信(ぽぴ王子さんの記事)
ありがとうございます。

Protected Shared Sub Main()
    Dim Loc_Path As String
    Loc_Path = Application.ExecutablePath
    If My.Computer.FileSystem.FileExists(Loc_Path) = True Then
        Dim hMutex As New System.Threading.Mutex(True, Application.ExecutablePath)

        If hMutex.WaitOne(0, False) = True Then
            Application.Run(New Form1())
        End If

        GC.KeepAlive(hMutex)

        hMutex.Close()

    End If
End Sub

で試してみましたが、Application.ExecutablePathがSystem.IO.DirectoryNotFoundExceptionでエラーになります。

Dim hMutex As New System.Threading.Mutex(True, Application.ExecutablePath)
の記述に問題があるのでしょうか?
■No18805に返信(よしさんの記事)

> Dim hMutex As New System.Threading.Mutex(True, Application.ExecutablePath)
> の記述に問題があるのでしょうか?

そうですね。私も試してみましたが、その部分でエラーになりますね。
で、脳裏にうっすらとあった記憶ですが、Mutex には "\" は使えなかったように
記憶しています。
(Win32API の CreateMutex のヘルプを見ると書いてあります)

ということで、Replace メソッドなどで "\" を別の文字(例えば "_" )に変換して
あげれば動くと思います。
■No18806に返信(ぽぴ王子さんの記事)
> ということで、Replace メソッドなどで "\" を別の文字(例えば "_" )に変換して
> あげれば動くと思います。

変換するならば、パスとして使用できない文字が望ましいです。
('/', など)
■No18808に返信(じゃんぬねっとさんの記事)

> 変換するならば、パスとして使用できない文字が望ましいです。
> ('/', など)

なるほど。確かにそうですね。
_ に変換してしまうと
 C:\aa\bb.exe と
 C:\aa_bb.exe が
同一として見なされてしまいますからね。

フォローありがとうございます。
■No18806に返信(ぽぴ王子さんの記事)
ありがとうございました。解決出来ました。

Public Sub Main()
Dim Loc_Path As String
Loc_Path = Application.ExecutablePath.Replace("\", "/")

Try
Dim hMutex As New System.Threading.Mutex(True, Loc_Path)

If hMutex.WaitOne(0, False) = True Then
Application.Run(New Form1())

End If

GC.KeepAlive(hMutex)

hMutex.Close()

Catch Loc_Exception As Exception
Form1.ShowDialog()

End Try

End Sub

上記処理で確認出来ました。
どうもありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板