71 lines
2.4 KiB
C#
71 lines
2.4 KiB
C#
using System;
|
|||
|
|
using System.IO;
|
||
|
|
using System.IO.Pipes;
|
||
|
|
using System.Text;
|
||
|
|
using System.Text.Json;
|
||
|
|
using PCL.Core.App.IoC;
|
||
|
|
using PCL.Core.IO;
|
||
|
|
using PCL.Core.Utils;
|
||
|
|
|
||
|
|
namespace PCL.Core.App.Essentials;
|
||
|
|
|
||
|
|
[LifecycleService(LifecycleState.BeforeLoading, Priority = -2134567890)]
|
||
|
|
[LifecycleScope("single-instance", "单例", false)]
|
||
|
|
public sealed partial class SingleInstanceService
|
||
|
|
{
|
||
|
|
private static FileStream? _lockStream;
|
||
|
|
private static readonly string _LockFilePath = Path.Combine(Paths.SharedLocalData, "instance.lock");
|
||
|
|
|
||
|
|
private static void _TryRpc(string processId, string content)
|
||
|
|
{
|
||
|
|
var pipeName = $"{RpcService.PipePrefix}@{processId}";
|
||
|
|
using var pipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut);
|
||
|
|
pipe.Connect(1000);
|
||
|
|
using var sw = new StreamWriter(pipe, PipeComm.PipeEncoding);
|
||
|
|
sw.WriteLine(content);
|
||
|
|
sw.Write(PipeComm.PipeEndingChar);
|
||
|
|
sw.Flush();
|
||
|
|
}
|
||
|
|
|
||
|
|
[LifecycleStart]
|
||
|
|
private static void _Start()
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var stream = File.Open(_LockFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
|
||
|
|
Context.Debug("未发现重复实例,正在向单例锁写入信息");
|
||
|
|
using var sw = new StreamWriter(stream, Encoding.ASCII, 8, true);
|
||
|
|
sw.Write(Basics.CurrentProcessId);
|
||
|
|
sw.Flush();
|
||
|
|
_lockStream = stream;
|
||
|
|
}
|
||
|
|
catch (Exception)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
using var stream = File.Open(_LockFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
|
|
using var reader = new StreamReader(stream);
|
||
|
|
var pid = reader.ReadToEnd();
|
||
|
|
Context.Info($"发现重复实例 {pid},尝试传递参数并拉起主窗口");
|
||
|
|
try
|
||
|
|
{
|
||
|
|
_TryRpc(pid, "REQ cli\n" + JsonSerializer.Serialize(StartupService.UnhandledCommands, JsonCompat.SerializerOptions));
|
||
|
|
_TryRpc(pid, "REQ activate");
|
||
|
|
}
|
||
|
|
catch (Exception ex) { Context.Warn("RPC 通信失败", ex); }
|
||
|
|
}
|
||
|
|
catch (Exception ex) { Context.Error("读取单例锁出错", ex); }
|
||
|
|
finally { Context.RequestExit(1); }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
[LifecycleStop]
|
||
|
|
private static void _Stop()
|
||
|
|
{
|
||
|
|
if (_lockStream is null) return;
|
||
|
|
Context.Debug("正在删除单例锁");
|
||
|
|
_lockStream.Dispose();
|
||
|
|
File.Delete(_LockFilePath);
|
||
|
|
}
|
||
|
|
}
|