命名管道服务器不听

时间:2013-10-18 17:54:54

标签: c# c#-3.0 named-pipes

我正在尝试创建一个简单地坐着并侦听命名管道上的消息的Windows服务。但它不起作用。尝试连接到命名管道只是超时,当我在Process Explorer中查看服务进程的进程句柄时,我看不到命名管道。

这是我到目前为止所做的:

namespace Service
{
    class Service : ServiceBase
    {
        Thread workerThread;
        static bool serviceStarted = false;
        static PipeSecurity pipeSecurity = new PipeSecurity();        

        public Service()
        {
            this.ServiceName = "Service";
            this.EventLog.Log = "Application";
            this.EventLog.Source = "ServiceName";
            this.CanHandlePowerEvent = false;
            this.CanHandleSessionChangeEvent = false;
            this.CanPauseAndContinue = false;
            this.CanShutdown = true;
            this.CanStop = true;
        }

        static void Main()
        {
            ServiceBase.Run(new Service());
        }

        protected override void OnStart(string[] args)
        {                
            base.OnStart(args);

            pipeSecurity.AddAccessRule(new PipeAccessRule("Authenticated Users", PipeAccessRights.ReadWrite, AccessControlType.Allow));
            pipeSecurity.AddAccessRule(new PipeAccessRule(WindowsIdentity.GetCurrent().User, PipeAccessRights.FullControl, AccessControlType.Allow));

            ThreadStart threadStart = new ThreadStart(WorkerThread);
            workerThread = new Thread(threadStart);
            workerThread.Start();
            serviceStarted = true;    
        }

        protected override void OnStop()
        {                
            base.OnStop();
            serviceStarted = false;
            workerThread.Join(new TimeSpan(0, 0, 30)); 
        }

        protected override void OnShutdown()
        {
            base.OnShutdown();
            serviceStarted = false;
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }

        private void WorkerThread()
        {
            while (serviceStarted)
            {
                try
                {
                    using (NamedPipeServerStream pipeServerStream = new NamedPipeServerStream("PipeName", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.None, 128, 128, pipeSecurity))
                    {
                        pipeServerStream.WaitForConnection();
                        byte[] buffer = new byte[128];
                        StringBuilder message = new StringBuilder();
                        do
                        {
                            int len = pipeServerStream.Read(buffer, 0, buffer.Length);
                            message.Append(Encoding.UTF8.GetString(buffer, 0, len));
                        }
                        while (!pipeServerStream.IsMessageComplete);
                        EventLog.WriteEntry(message.ToString());
                    }
                }
                catch(Exception ex)
                {

                }
                finally
                {
                    if (serviceStarted)
                        Thread.Sleep(100);
                }
            }
            Thread.CurrentThread.Abort();
        }
    }
}

似乎没有创建命名管道。有任何想法吗?当我尝试通过Powershell连接时:

PS C:\> $Client = New-Object System.IO.Pipes.NamedPipeClientStream(".", "PipeName", [System.IO.Pipes.PipeDirection]::Out)
PS C:\> $Client.Connect(1000)

Exception calling "Connect" with "1" argument(s): "The operation has timed out."
At line:1 char:1
+ $Client.Connect(1000)

1 个答案:

答案 0 :(得分:3)

   new NamedPipeServerStream("PipeName", ...)

只有在同一会话中运行的进程才能访问该管道。哪个是服务的会话0。您的Powershell程序在桌面会话上运行。要使其对所有会话可见,您必须在名称前添加"Global\\"

不过,请不要犹豫,添加一些日志记录,这样就可以确定管道服务器即将调用WaitForConnection()。这消除了你(和我们的)管道实际上正在倾听的相当大的疑问。使用空的catch块会产生太多的FUD。

相关问题