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