NamedPipes 在 Windows 服务中抛出异常

发布于 2024-09-29 22:17:03 字数 3984 浏览 0 评论 0原文

我创建了一个 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)

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

这是我为该线程提供的代码:

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 = "StackOVerFlowPipeCode";
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;
    }
}

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

I have created a windows service which allows communications via namedpipes.

This code worked fine when I wrote some unit tests to spin up the pipes and test the communication, but now I have installed the same code in my windows service I get the following error:

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)

Now I did some googling and found this post in stackoverflow > POST But I implemented this (apart from the ps.AddAccessRule(pa); as that made no reference to was pa was)
and I get the same error.

this is the code I have for the thread:

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();

any help will be great.

Ok here is the code that is running the listener:

the windows service:

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();

}

the listener code:

private const String pipeName = "StackOVerFlowPipeCode";
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;
    }
}

Exception message found: All pipe instances are busy.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白芷 2024-10-06 22:17:03

事实证明我的整个实现是有缺陷的,我删除了很多代码并重写了它并且它起作用了。我删除了 ListenForMessage() 中的代码,并将其替换为 ServerThread() 中的代码,然后还更改了服务调用此方法的方式,将其更改为计时器中的线程。它起作用了。

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

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

Turns out my whole implementation was flawed, I deleted a lot of code and rewrote it and it worked. I removed code from in ListenForMessage() and replaced it with the code from ServerThread() and then also changed how the service was calling this, to a thread from a timer. and it worked.

well sort of, the code after the message is received (shown as //Do Stuff in the above) does work, but at least this task is complete.

note: never just copy and past code and take it for granted always read it and understand it.

老街孤人 2024-10-06 22:17:03

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

\\.\pipe\pipename

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


编辑:进一步检查(查看NamedPipeServerStream 示例)情况可能并非如此。因此需要查看异常的完整详细信息:Message 属性和运行时类型。

Named Pipe names need to be in the format:

\\.\pipe\pipename

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


EDIT: On further examination (looking at the NamedPipeServerStream sample) this might not be the case. So need to see the full details of the exception: Message property and run time type.

噩梦成真你也成魔 2024-10-06 22:17:03

您没有包含异常。消息,但根据 NamedPipeServerStream 的 MSDN 页面,IOException 表示“已超出服务器实例的最大数量”。这是你得到的例外吗?

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

You didn't include the exception.Message but According to the MSDN page for NamedPipeServerStream, the IOException is for "The maximum number of server instances has been exceeded." is this the exception you are getting?

If so, what is numThreads set to, and is it possible you have another instance of you app running? (e.g. the unit test you were experimenting with?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文