From c10eae6596803bae3ef8e98e4f9eb8e648e6a168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BD=BB=E8=AF=AD?= Date: Sun, 17 May 2026 04:20:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E7=9A=84=E5=8D=95=E4=BE=8B?= =?UTF-8?q?=E9=94=81=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plain Craft Launcher 2/Application.xaml.vb | 62 ++++++++++++++++------ 1 file changed, 47 insertions(+), 15 deletions(-) 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