我是第一次使用命名管道.我的最终目标是让一个既能充当客户端、服务器又能独立工作的可执行文件.服务器可以具有提升的权限.

我对来回转接有困难.首先,除第一次外,每次写回客户端时都以‘?’开头.互联网上说这是一个编码问题,但它是同一个函数(WriteClient)正在做这件事,所以我不能确定为什么第一次会不同.(打印输出也证实了作者和读者每次都说了相同的编码)第二,我想确保我适当地关闭了连接.它花了一些试错的时间.

Readout from Client
In this version, I told it to print the encoding as well to confirm it didn't change.

Connected.
Version Installed: 1.2.8
?Latest Version: 1.2.85
?Update Needed
?Run again without '-Check' to perform a silent installation.
?Close
Connection closed.

100

using System;
using System.Diagnostics;
using System.Xml.Linq;
using System.Runtime.Versioning;
using System.IO.Pipes;
using System.Text;
using System.Net;
using System.ServiceProcess;
using System.Security.Authentication.ExtendedProtection;

[SupportedOSPlatform("windows")]

class DAQUpdate
{
    static void Main(string[] args)
    {       
        if (args.Length > 0)
        {

                //Check if the same program is running as a service. If so, use that as it will have elevated previleges 
                try
                {
                    using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "DAQUpdater", PipeDirection.InOut))
                    {
                        //Connect to the service with a 1 second timeout. This will return an error on timeout
                        pipeClient.Connect(1);
                        //Double check if connected for reasons.
                        if(pipeClient.IsConnected)
                        {
                            Console.WriteLine("Connected.");

                            // Send the args to the server
                            using (StreamWriter writer = new StreamWriter(pipeClient,Encoding.UTF8,-1,true))
                            {
                                //Packages the args with ; to separate since I can't pass objects
                                writer.WriteLine(string.Join(';', args));
                                writer.Flush();
                            }

                            //Read all responses from the server as it gives them. The final response will be Close
                            string response = "";                               
                            using (StreamReader reader = new StreamReader(pipeClient, Encoding.UTF8))
                            {
                                while(!response.Contains("Close"))
                                {                                    
                                    response = reader.ReadLine();
                                    Console.WriteLine(response);
                                }
                                pipeClient.Close();
                            }
                            Console.WriteLine("Connection closed.");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.WriteLine("No Connection.");
                }            
        }
        else
        {
            NamedPipeServer.runServer();
        }
    }
    public static void update(string[] args)
    {
        NamedPipeServer.writeClient("hello");
        NamedPipeServer.writeClient(args[0]);
        NamedPipeServer.writeClient("Testing");
        NamedPipeServer.writeClient("Close");
    }
    
}

Server Functions

// NamedPipeServer.cs

using System.IO.Pipes;
using System.Text;

public class NamedPipeServer
{
    private static NamedPipeServerStream pipeServer;
    public static void runServer()
    {
        try
        {            
            while(true)
            {
                //Changed to global so other functions can call writeClient and send messages to the client from anywhere
                pipeServer = new NamedPipeServerStream("DAQUpdater", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

                {
                    Console.WriteLine("Waiting for connection...");
                    pipeServer.WaitForConnection();
                    Console.WriteLine("Client connected.");

                    // Read and process the command from the client
                    using (StreamReader reader = new StreamReader(pipeServer, Encoding.UTF8,true,-1,true ))
                    {
                        string command = reader.ReadLine();
                        string[] commandargs = command.Split(';');
                        Console.WriteLine($"Received command: {commandargs[0]}");

                        //Run the check for updates program which will also write to the client
                        DAQUpdate.update(commandargs);

                        // Send a response back to the client if needed
                        using (StreamWriter writer = new StreamWriter(pipeServer, Encoding.UTF8, -1 , true))
                        {
                            writer.WriteLine("Close");
                            writer.Flush();
                        }
                    }
                    pipeServer.Close();
                    Console.WriteLine("Connection closed.");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
    public static void writeClient(string messageTxt)
    {
        //allows other functions to send update messages to the client
        if(pipeServer != null)
        {
            if(pipeServer.IsConnected)
            {
                using (StreamWriter writer = new StreamWriter(pipeServer, Encoding.UTF8, -1 , true))
                {
                    Console.WriteLine(writer.Encoding);
                    writer.WriteLine(messageTxt);
                    writer.Flush();
                }
            }
        }                
    }
}


推荐答案

您将为每一行创建一个单独的StreamWriter,这将从为您指定的Encoding发出前导开始-Encoding.UTF8包括字节顺序标记的前导.

你们看不到第一行,因为StreamReader很可能会悄悄地把它从输入的开头go 掉.(老实说,我记不清作者/读者什么时候发出/剥离它的细节了.)

我建议您在Utf8EncodingWithoutPreamble处创建一个简单的静态属性,通过new Utf8Encoding(false)进行初始化.如果你每次写作时都用到这一点,你就不会得到前言.

你可以创建一个StreamWriter,并保持它打开,所以它只会写一个将被剥离的前导.

Or你可以完全省go StreamWriter,只需使用:

pipeServer.Write(Encoding.Utf8.GetBytes(messageTxt + "\n"));

(撇开其他内容不谈,我建议使用定义良好的换行符,而不是缺省的"无论平台缺省换行符是什么").

Csharp相关问答推荐

ASP.NET Core -是否可以对所有最小API端点应用过滤器?

哪个nuget包含SecurityStampValidatorOptions

在C#WinUI中,一个关于System的崩溃."由于未知原因导致执行不例外"

如何模拟耐久任务客户端在统一测试和获取错误在调度NewsListationInstanceAsync模拟设置

无法通过绑定禁用条目

当前的文化决定了错误的文化

在.NET MAUI.NET 8中如何防止按钮点击时出现灰色反馈

如何通过属性初始化器强制初始化继承记录内的属性?

避免只读记录 struct 中的防御副本

我可以查看我们向应用程序洞察发送了多少数据吗?

有条件地定义预处理器指令常量

岛屿和框架中的自定义控件库.Navigate-AccessViolationException

用于请求用户返回列表的C#Google API

为什么当我try 为玩家角色设置动画时,没有从文件夹中拉出正确的图像?

为什么Swashbakle/Swagger在参数中包含变量名?

C#中COM对象的实际地址

在C#中删除多个不同名称的会话

我如何为我的Blazor应用程序构建一个动态教程标注?

无法停止PowerShell中的低级挂钩(c#挂钩)

阻止CLR释放已封送的双字符指针的内存?