37fc06e274
- 子命令 save/notify/input/cleanup:纯互操作 IPC,不加载 Avalonia
- 命名管道:瘦客户端投递请求,Host 未运行时自动拉起并重试
- 每会话状态文件 %TEMP%\claude-notify-{id}.json,保存前台窗口与 prompt
- Host 单例互斥量 + 管道监听,收到请求切回 UI 线程弹窗
- stdin 改为 UTF-8 原始字节读取,修复中文乱码与读不到的问题
- 符合 Claude Code 插件规范的 .claude-plugin 与 hooks 结构
80 lines
1.8 KiB
C#
80 lines
1.8 KiB
C#
using System;
|
||
using System.Diagnostics;
|
||
using System.IO.Pipes;
|
||
using System.Text;
|
||
using System.Text.Json;
|
||
using System.Threading;
|
||
using Notify.Serialization;
|
||
|
||
namespace Notify.Ipc;
|
||
|
||
/// <summary>
|
||
/// 瘦客户端侧:把一条 PipeMessage 发给 Host,Host 不在则拉起后重试
|
||
/// </summary>
|
||
public static class PipeClient
|
||
{
|
||
public static bool Send(PipeMessage message)
|
||
{
|
||
var json = JsonSerializer.Serialize(message, AppJsonContext.Default.PipeMessage);
|
||
var bytes = Encoding.UTF8.GetBytes(json);
|
||
|
||
if (TrySend(bytes, 300))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
// Host 未运行:拉起后等待其管道就绪再重试,最多约 5 秒
|
||
StartHost();
|
||
for (var i = 0; i < 50; i++)
|
||
{
|
||
Thread.Sleep(100);
|
||
if (TrySend(bytes, 300))
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
private static bool TrySend(byte[] bytes, int timeoutMs)
|
||
{
|
||
try
|
||
{
|
||
using var client = new NamedPipeClientStream(".", IpcConstants.PipeName, PipeDirection.Out);
|
||
client.Connect(timeoutMs);
|
||
client.Write(bytes, 0, bytes.Length);
|
||
client.Flush();
|
||
return true;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
private static void StartHost()
|
||
{
|
||
try
|
||
{
|
||
var exe = Environment.ProcessPath;
|
||
if (exe is null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
Process.Start(new ProcessStartInfo
|
||
{
|
||
FileName = exe,
|
||
Arguments = "host",
|
||
UseShellExecute = false,
|
||
CreateNoWindow = true,
|
||
});
|
||
}
|
||
catch
|
||
{
|
||
// 拉起失败则发送会重试超时后放弃
|
||
}
|
||
}
|
||
}
|