NamedPipes выдает исключение в службу Windows - PullRequest
2 голосов
/ 29 октября 2010

Я создал службу 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); поскольку в нем не упоминалось, что 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 = "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;
    }
}

Обнаружено исключительное сообщение: все экземпляры канала заняты.

Ответы [ 3 ]

2 голосов
/ 29 октября 2010

Оказывается, вся моя реализация была ошибочной, я удалил много кода и переписал его, и это сработало. Я удалил код из ListenForMessage () и заменил его кодом из ServerThread (), а затем также изменил способ вызова этой службы потоком из таймера. и это сработало.

Хорошо, код после получения сообщения (показанный как // Do Stuff в вышеприведенном) работает, но по крайней мере эта задача выполнена.

примечание: никогда не копируйте и не берите код, и принимайте его как должное, всегда читайте и понимайте его.

1 голос
/ 29 октября 2010

Имена именованных каналов должны быть в формате:

\\.\pipe\pipename

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


РЕДАКТИРОВАТЬ: При дальнейшем рассмотрении (глядя на NamedPipeServerStream образец) это может быть не так. Поэтому необходимо просмотреть полную информацию об исключении: Message свойство и тип времени выполнения.

0 голосов
/ 29 октября 2010

Вы не включили исключение. Сообщение, но согласно странице MSDN для NamedPipeServerStream, IOException для "Превышено максимальное количество экземпляров сервера".это исключение вы получаете?

Если это так, для чего задано значение numThreads, и возможно ли, что у вас запущен еще один экземпляр приложения?(например, юнит-тест, с которым вы экспериментировали?)

...