feat: 新的单例锁实现

This commit is contained in:
林轻语
2026-05-17 04:20:31 +08:00
committed by GitHub
parent 409e1ccdc1
commit c10eae6596
+47 -15
View File
@@ -93,22 +93,22 @@ RetryCacheCheck:
DirectoryUtils.Create(PathAppdata) DirectoryUtils.Create(PathAppdata)
'要求单例 '要求单例
If BuildType <> BuildTypes.Debug Then If BuildType <> BuildTypes.Debug Then
Dim ShouldWaitForExit As Boolean = e.Args.Length > 0 AndAlso e.Args(0) = "--wait" '要求等待已有的 PCL 退出 If Not GetProgramLock(FileLockPath) Then
Dim WaitRetryCount As Integer = 0 Dim IsLocked = False
WaitRetry: Dim ShouldWaitForExit As Boolean = e.Args.Length > 0 AndAlso e.Args(0) = "--wait" '要求等待已有的 PCL 退出
Dim WindowHwnd As IntPtr = FindWindow(Nothing, "Plain Craft Launcher ") If Not ShouldWaitForExit Then
If WindowHwnd = IntPtr.Zero Then FindWindow(Nothing, "Plain Craft Launcher 2 ") DropToTopByLock(FileLockPath)
If WindowHwnd <> IntPtr.Zero Then Beep()
If ShouldWaitForExit AndAlso WaitRetryCount < 20 Then '至多等待 10 秒 Environment.Exit(ProcessReturnValues.Cancel)
WaitRetryCount += 1
Thread.Sleep(500)
GoTo WaitRetry
End If End If
'将已有的 PCL 窗口拖出来 For i = 0 To 10
ShowWindowToTop(WindowHwnd) If GetProgramLock(FileLockPath) Then
'播放提示音并退出 IsLocked = True
Beep() Exit For
Environment.[Exit](ProcessReturnValues.Cancel) End If
Thread.Sleep(500)
Next
If Not IsLocked Then DropToTopByLock(FileLockPath)
End If End If
End If End If
'设置 ToolTipService 默认值 '设置 ToolTipService 默认值
@@ -162,6 +162,38 @@ WaitRetry:
FormMain.EndProgramForce(ProcessReturnValues.Exception) FormMain.EndProgramForce(ProcessReturnValues.Exception)
End Try End Try
End Sub End Sub
Private Shared KernelLock As Mutex
''' <summary>
''' 尝试获取单例锁
''' </summary>
''' <param name="LockPath">文件锁位置</param>
''' <returns>一个值用于指示是否获得文件锁</returns>
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
''' <summary>
''' 从文件锁中尝试拖出进程
''' </summary>
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 Private Sub Application_SessionEnding(sender As Object, e As SessionEndingCancelEventArgs) Handles Me.SessionEnding