diff --git a/Plain Craft Launcher 2/Application.xaml.vb b/Plain Craft Launcher 2/Application.xaml.vb
index 0824938..f994444 100644
--- a/Plain Craft Launcher 2/Application.xaml.vb
+++ b/Plain Craft Launcher 2/Application.xaml.vb
@@ -93,22 +93,22 @@ RetryCacheCheck:
DirectoryUtils.Create(PathAppdata)
'要求单例
If BuildType <> BuildTypes.Debug Then
- Dim ShouldWaitForExit As Boolean = e.Args.Length > 0 AndAlso e.Args(0) = "--wait" '要求等待已有的 PCL 退出
- Dim WaitRetryCount As Integer = 0
-WaitRetry:
- Dim WindowHwnd As IntPtr = FindWindow(Nothing, "Plain Craft Launcher ")
- If WindowHwnd = IntPtr.Zero Then FindWindow(Nothing, "Plain Craft Launcher 2 ")
- If WindowHwnd <> IntPtr.Zero Then
- If ShouldWaitForExit AndAlso WaitRetryCount < 20 Then '至多等待 10 秒
- WaitRetryCount += 1
- Thread.Sleep(500)
- GoTo WaitRetry
+ If Not GetProgramLock(FileLockPath) Then
+ Dim IsLocked = False
+ Dim ShouldWaitForExit As Boolean = e.Args.Length > 0 AndAlso e.Args(0) = "--wait" '要求等待已有的 PCL 退出
+ If Not ShouldWaitForExit Then
+ DropToTopByLock(FileLockPath)
+ Beep()
+ Environment.Exit(ProcessReturnValues.Cancel)
End If
- '将已有的 PCL 窗口拖出来
- ShowWindowToTop(WindowHwnd)
- '播放提示音并退出
- Beep()
- Environment.[Exit](ProcessReturnValues.Cancel)
+ For i = 0 To 10
+ If GetProgramLock(FileLockPath) Then
+ IsLocked = True
+ Exit For
+ End If
+ Thread.Sleep(500)
+ Next
+ If Not IsLocked Then DropToTopByLock(FileLockPath)
End If
End If
'设置 ToolTipService 默认值
@@ -162,6 +162,38 @@ WaitRetry:
FormMain.EndProgramForce(ProcessReturnValues.Exception)
End Try
End Sub
+
+ Private Shared KernelLock As Mutex
+
+ '''
+ ''' 尝试获取单例锁
+ '''
+ ''' 文件锁位置
+ ''' 一个值用于指示是否获得文件锁
+ Private Function GetProgramLock(LockPath As String) As Boolean
+ Try
+ Dim IsLocked = False
+ KernelLock = New Mutex(True, "Plain Craft Launcher", IsLocked)
+ If Not IsLocked Then Return False
+ Logger.Info("获取单例锁成功")
+ File.WriteAllText(LockPath, Process.GetCurrentProcess().Id.ToString())
+ Return IsLocked
+ Catch ex As Exception
+
+ End Try
+
+ Return False
+ End Function
+
+ '''
+ ''' 从文件锁中尝试拖出进程
+ '''
+ Public Sub DropToTopByLock(LockPath As String)
+ Dim Content = File.ReadAllBytes(LockPath)
+ Dim Pid As Integer
+ If Not Integer.TryParse(Encoding.UTF8.GetString(Content), Pid) Then Return
+ ShowWindowToTop(Process.GetProcessById(Pid).MainWindowHandle)
+ End Sub
'结束
Private Sub Application_SessionEnding(sender As Object, e As SessionEndingCancelEventArgs) Handles Me.SessionEnding