初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user