Files
notify/Notify/Ipc/PipeServer.cs
T
chuan 37fc06e274 feat: 打通 hook CLI 与命名管道链路(P0)
- 子命令 save/notify/input/cleanup:纯互操作 IPC,不加载 Avalonia
- 命名管道:瘦客户端投递请求,Host 未运行时自动拉起并重试
- 每会话状态文件 %TEMP%\claude-notify-{id}.json,保存前台窗口与 prompt
- Host 单例互斥量 + 管道监听,收到请求切回 UI 线程弹窗
- stdin 改为 UTF-8 原始字节读取,修复中文乱码与读不到的问题
- 符合 Claude Code 插件规范的 .claude-plugin 与 hooks 结构
2026-06-22 14:40:22 +08:00

59 lines
1.6 KiB
C#

using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Notify.Serialization;
namespace Notify.Ipc;
/// <summary>
/// Host 侧命名管道监听:每个连接读取一条 PipeMessage 并回调
/// </summary>
public sealed class PipeServer
{
private readonly Action<PipeMessage> _onMessage;
public PipeServer(Action<PipeMessage> onMessage) => _onMessage = onMessage;
public void Start() => Task.Run(RunLoopAsync);
private async Task RunLoopAsync()
{
while (true)
{
try
{
using var server = new NamedPipeServerStream(
IpcConstants.PipeName,
PipeDirection.In,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
await server.WaitForConnectionAsync().ConfigureAwait(false);
using var ms = new MemoryStream();
await server.CopyToAsync(ms).ConfigureAwait(false);
var json = Encoding.UTF8.GetString(ms.ToArray());
if (string.IsNullOrWhiteSpace(json))
{
continue;
}
var msg = JsonSerializer.Deserialize(json, AppJsonContext.Default.PipeMessage);
if (msg is not null)
{
_onMessage(msg);
}
}
catch
{
// 单个连接出错不影响后续监听
}
}
}
}