NamedPipes 在 Windows 服务中引发异常

Posted

技术标签:

【中文标题】NamedPipes 在 Windows 服务中引发异常【英文标题】:NamedPipes throwing an exception in windows service 【发布时间】:2010-10-29 10:40:08 【问题描述】:

我创建了一个允许通过命名管道进行通信的 Windows 服务。

当我编写一些单元测试来启动管道并测试通信时,这段代码运行良好,但现在我在我的 Windows 服务中安装了相同的代码,我收到以下错误:

Exception Info: System.IO.IOException
Stack:
       at System.IO.__Error.WinIOError(Int32, System.String)
       at System.IO.Pipes.NamedPipeServerStream.Create(System.String, System.IO.Pipes.PipeDirection, Int32, System.IO.Pipes.PipeTransmissionMode, System.IO.Pipes.PipeOptions, Int32, Int32, System.IO.Pipes.PipeAccessRights, SECURITY_ATTRIBUTES)
       at System.IO.Pipes.NamedPipeServerStream..ctor(System.String, System.IO.Pipes.PipeDirection, Int32, System.IO.Pipes.PipeTransmissionMode, System.IO.Pipes.PipeOptions, Int32, Int32, System.IO.Pipes.PipeSecurity, System.IO.HandleInheritability, System.IO.Pipes.PipeAccessRights)
       at System.IO.Pipes.NamedPipeServerStream..ctor(System.String, System.IO.Pipes.PipeDirection, Int32, System.IO.Pipes.PipeTransmissionMode,     
System.IO.Pipes.PipeOptions, Int32, Int32, System.IO.Pipes.PipeSecurity)
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart(System.Object)

现在我做了一些谷歌搜索,在 *** 中找到了这篇文章 > POST 但我实现了这个(除了 ps.AddAccessRule(pa); 因为没有提到是 pa 是) 我得到了同样的错误。

这是我的线程代码:

var pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow));
pipeSecurity.AddAccessRule(new PipeAccessRule("CREATOR OWNER", PipeAccessRights.FullControl, AccessControlType.Allow));
pipeSecurity.AddAccessRule(new PipeAccessRule("SYSTEM", PipeAccessRights.FullControl, AccessControlType.Allow));

var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, numThreads, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024, pipeSecurity);    

pipeServer.WaitForConnection();

任何帮助都会很棒。

好的,这是运行监听器的代码:

windows 服务:

public static System.Timers.Timer Timer = new System.Timers.Timer();

public void Start()

    Timer.Elapsed += (HeartBeat);
    //Timer.Interval = 100; //Live
    Timer.Interval = 2000; //Debug
    Timer.Start();


public void Stop()

    Timer.Stop();


private static void HeartBeat(object sender, ElapsedEventArgs e)

    //listen for a message
    ListenForMessage();


监听代码:

private const String pipeName = "***PipeCode";
private const int numThreads = 10;

public static void ListenForMessage()

    int i;
    var servers = new Thread[numThreads];

    for (i = 0; i < numThreads; i++)
    
        servers[i] = new Thread(ServerThread);
        servers[i].Start();
    

    Thread.Sleep(250);

    while (i > 0)
    
        for (var j = 0; j < numThreads; j++)
        
            if (servers[j] == null) continue;
            if (!servers[j].Join(250)) continue;

            servers[j] = null;

            i--;    // decrement the thread watch count
        
    


private static void ServerThread(object data)

    try
    
        var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, numThreads);

        pipeServer.WaitForConnection();

        var ss = new StreamString(pipeServer);
        ss.WriteString(pipeName);

        var message = ss.ReadString();

        //DO STUFF HERE WITH MESSAGE

        pipeServer.Close();
    
    catch (Exception ex)
    
        //CRY LIKE A BABY WHO LOST HIS TEDDY
        throw ex;
    

发现异常消息:所有管道实例都忙。

【问题讨论】:

【参考方案1】:

原来我的整个实现有缺陷,我删除了很多代码并重写了它,它工作了。我从 ListenForMessage() 中删除了代码,并将其替换为 ServerThread() 中的代码,然后还将服务调用它的方式更改为来自计时器的线程。并且成功了。

好吧,收到消息后的代码(上面显示为//Do Stuff)确实有效,但至少这个任务完成了。

注意:永远不要只是复制和过去的代码并认为它​​是理所当然的,始终阅读并理解它。

【讨论】:

您应该对您的问题进行编辑,除非您打算在此处发布您的实际代码,然后将其标记为答案,以便其他 SO'ers 知道您做了哪些不同的事情,以便他们也可以学习。仅供参考。 上面的评论解释了我是如何做到的,代码与原始问题完全相同,但谢谢。【参考方案2】:

命名管道名称需要采用以下格式:

\\.\pipe\管道名称

请参阅 CreatedNamedPipe Win32 API:http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx


编辑:进一步检查(查看NamedPipeServerStream 示例)可能并非如此。所以需要查看异常的全部细节:Message属性和运行时类型。

【讨论】:

【参考方案3】:

您没有包含 exception.Message,但根据 NamedPipeServerStream 的 MSDN 页面,IOException 是“已超过服务器实例的最大数量”。这是你得到的例外吗?

如果是这样,numThreads 设置为多少,您是否有可能正在运行您的应用程序的另一个实例? (例如,您正在试验的单元测试?)

【讨论】:

我确实包含了异常?我设置的最大数量是10,管道甚至没有被创建,它在我启动服务后就爆炸了 您确定您的测试应用程序不再运行吗?而且,您包含了异常的类型 (IOException),但没有包含 Message。 我现在已经添加了我正在使用的代码,会不会是心跳一直在旋转监听器?

以上是关于NamedPipes 在 Windows 服务中引发异常的主要内容,如果未能解决你的问题,请参考以下文章

如果客户端和服务器在不同的机器上,则无法在 NamedPipes 中模拟权限

使用同步 NamedPipes 同步读写

新安装sql server数据库后设置

如何将多个选项传递给 Firefox 中引导轮播的可选选项对象?

自动布局中引脚和对齐之间的区别?

在一个多模块的python项目中,如何在子模块中引用项目的根目录?