c# - Winforms和服务之间的命名管道只能连接一次
问题描述
我正在制作一个简单的应用程序来尝试我正在制作的应用程序的命名管道。我最初可以连接到管道并写入使用正在侦听输入的服务指定的文件。如果我重新启动我的 winforms 应用程序并尝试连接到管道,它只会挂在 .Connect() 方法上。如果我重新启动我的服务,那么我可以再次连接我的 winforms 应用程序......但只能连接一次(直到我再次重新启动服务)。
这是我的 Windows 服务上的 NamedPipeServerStream。
protected override void OnStart(string[] args)
{
StartPipe();
}
protected override void OnStop()
{
}
public void StartPipe()
{
FileStream fs = new FileStream(@"C:\Users\Nate\Desktop\PipeService.txt", FileMode.OpenOrCreate, FileAccess.Write);
Task.Run(() =>
{
var server = new NamedPipeServerStream("PipeService3");
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
StreamWriter writer = new StreamWriter(fs);
writer.WriteLine(line);
writer.Flush();
}
});
}
这是我的 Winforms 应用程序中的 NamePipeClientStream 部分
public StreamWriter writer;
public NamedPipeClientStream client;
public Form1()
{
InitializeComponent();
client = new NamedPipeClientStream("PipeService3");
client.Connect();
writer = new StreamWriter(client);
}
private void sendButton_Click(object sender, EventArgs e)
{
string line = textBox1.Text;
writer.WriteLine(line);
writer.Flush();
}
这是我的解决方法,但我觉得有一种合法的方法可以做到这一点,而不是在每次有人打开 winforms 应用程序时停止和启动服务。
try
{
client.Connect(1000);
}
catch
{
var serviceController = ServiceController.GetServices();
var pipeService = serviceController.Where(s => s.DisplayName == "PipeService").FirstOrDefault();
pipeService.Stop();
pipeService.WaitForStatus(ServiceControllerStatus.Stopped);
pipeService.Start();
pipeService.WaitForStatus(ServiceControllerStatus.Running);
client.Connect();
}
解决方案
我可以通过将管道设置为递归来解决这个问题,所以只要客户端断开连接(在我的情况下,它只会是一个客户端),命名管道就会被处理掉,并命名一个具有相同管道的新管道。(还包括允许我的 winforms 应用程序作为非管理员仍然连接到以提升权限的服务启动的管道)
public void StartPipe()
{
System.Threading.Tasks.Task.Run(() =>
{
RecursivePipe();
});
}
public void RecursivePipe()
{
PipeSecurity pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow));
pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), PipeAccessRights.FullControl, AccessControlType.Allow));
var server = new NamedPipeServerStream("PipeService7", PipeDirection.InOut, 10, PipeTransmissionMode.Message, PipeOptions.WriteThrough, 1024, 1024, pipeSecurity);
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var lineArray = line.Split('$');
if (lineArray.Length == 4)
{
SetkeyValue(lineArray);
}
else if (lineArray.Length == 5)
{
setStartupStrat(lineArray);
}
else
{
DeleteKeyValue(lineArray);
}
}
server.Dispose();
server.Close();
RecursivePipe();
}
推荐阅读
- html - 为什么边界半径对图像不起作用?
- python - 部署期间未加载静态
- python - 在 Django 上提供具有不同编码的 csv 文件
- python - Sqlalchemy 数据库查询
- python - 操作数据帧
- php - 为什么codeigniter在服务器中突然停止工作
- excel - VBA 中的错误:在循环中选择不连续的单元格范围
- android - 将 UDP 数据包转换为字符串并显示在日志中
- python - 是否有一些不同的方法可以在 VS 代码中导入 RE,或者我是否缺少一些设置?
- java - HarmonyOS 相当于 Android 中的 android.graphics.Typeface 是什么?