@@ -91,24 +91,35 @@ RetryCacheCheck:
9191 End Try
9292 DirectoryUtils.Create(PathTemp & "Cache\" )
9393 DirectoryUtils.Create(PathAppdata)
94+
95+ # If DEBUG Then
96+ Dim FileLockPath = Path.Combine(PathAppdata.TrimEnd( "\" ), "PCL.dev.Lock" )
97+ # Else
98+ Dim FileLockPath = Path.Combine(PathAppdata.TrimEnd( "\" ), "PCL.Lock" )
99+ # End If
100+
94101 '要求单例
95102 If BuildType <> BuildTypes.Debug Then
96- Dim ShouldWaitForExit As Boolean = e.Args.Length > 0 AndAlso e.Args( 0 ) = "--wait" '要求等待已有的 PCL 退出
97- Dim WaitRetryCount As Integer = 0
98- WaitRetry:
99- Dim WindowHwnd As IntPtr = FindWindow( Nothing , "Plain Craft Launcher " )
100- If WindowHwnd = IntPtr.Zero Then FindWindow( Nothing , "Plain Craft Launcher 2 " )
101- If WindowHwnd <> IntPtr.Zero Then
102- If ShouldWaitForExit AndAlso WaitRetryCount < 20 Then '至多等待 10 秒
103- WaitRetryCount += 1
103+ If Not GetProgramLock(FileLockPath) Then
104+ Dim IsLocked = False
105+ Dim ShouldWaitForExit As Boolean = e.Args.Length > 0 AndAlso e.Args( 0 ) = "--wait" '要求等待已有的 PCL 退出
106+ If Not ShouldWaitForExit Then
107+ DropToTopByLock(FileLockPath)
108+ Beep()
109+ Environment.Exit(ProcessReturnValues.Cancel)
110+ End If
111+ For i = 0 To 10
112+ If GetProgramLock(FileLockPath) Then
113+ IsLocked = True
114+ Exit For
115+ End If
104116 Thread.Sleep( 500 )
105- GoTo WaitRetry
117+ Next
118+ If Not IsLocked Then
119+ DropToTopByLock(FileLockPath)
120+ Beep()
121+ Environment.Exit(ProcessReturnValues.Cancel)
106122 End If
107- '将已有的 PCL 窗口拖出来
108- ShowWindowToTop(WindowHwnd)
109- '播放提示音并退出
110- Beep()
111- Environment.[Exit](ProcessReturnValues.Cancel)
112123 End If
113124 End If
114125 '设置 ToolTipService 默认值
@@ -162,6 +173,38 @@ WaitRetry:
162173 FormMain.EndProgramForce(ProcessReturnValues.Exception)
163174 End Try
164175 End Sub
176+
177+ Private Shared KernelLock As Mutex
178+
179+ ''' <summary>
180+ ''' 尝试获取单例锁
181+ ''' </summary>
182+ ''' <param name="LockPath">文件锁位置</param>
183+ ''' <returns>一个值用于指示是否获得文件锁</returns>
184+ Private Function GetProgramLock(LockPath As String ) As Boolean
185+ Try
186+ Dim IsLocked = False
187+ KernelLock = New Mutex( True , "Local\Plain Craft Launcher" , IsLocked)
188+ If Not IsLocked Then Return False
189+ Logger.Info( "获取单例锁成功" )
190+ File.WriteAllText(LockPath, Process.GetCurrentProcess().Id.ToString())
191+ Return IsLocked
192+ Catch ex As Exception
193+
194+ End Try
195+
196+ Return False
197+ End Function
198+
199+ ''' <summary>
200+ ''' 从文件锁中尝试拖出进程
201+ ''' </summary>
202+ Public Sub DropToTopByLock(LockPath As String )
203+ Dim Pid As Integer
204+ If Not Integer .TryParse(File.ReadAllText(LockPath), Pid) Then Return
205+ Dim Handle = Process.GetProcessById(Pid)?.MainWindowHandle
206+ If Handle <> Intptr.Zero Then ShowWindowToTop(Handle)
207+ End Sub
165208
166209 '结束
167210 Private Sub Application_SessionEnding(sender As Object , e As SessionEndingCancelEventArgs) Handles Me .SessionEnding
0 commit comments