2010-10-29 16 views
1

J'ai créé un service Windows qui permet les communications via namedpipes.NamedPipes lançant une exception dans le service Windows

Ce code a bien fonctionné quand j'ai écrit quelques tests unitaires pour filer les tuyaux et tester la communication, mais maintenant je l'ai installé le même code dans mon service Windows, je reçois l'erreur suivante:

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) 

maintenant J'ai fait un peu de googling et trouvé ce post dans stackoverflow>POST Mais j'ai implémenté ceci (en dehors de ps.AddAccessRule (pa), car cela ne faisait pas référence à était pa) et j'obtiens la même erreur.

c'est le code que j'ai pour le fil:

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

toute aide sera grande.

Ok est le code ici qui exécute l'auditeur:

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

} 

le code auditeur:

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; 
    } 
} 

un message Exception trouvé: Toutes les instances de conduite sont occupés .

Répondre

1

Il s'avère que toute mon implémentation était défectueuse, j'ai supprimé beaucoup de code et l'ai réécrit et cela a fonctionné. J'ai enlevé le code de ListenForMessage() et l'ai remplacé par le code de ServerThread() et ai changé également comment le service l'appelait, à un fil d'un temporisateur. et ça a marché.

bien, le code après que le message est reçu (montré comme // Do Stuff dans le ci-dessus) fonctionne, mais au moins cette tâche est terminée.

note: ne jamais simplement copier et passer le code et le prendre pour acquis toujours le lire et le comprendre.

+0

Vous auriez dû faire une modification sur votre question à moins que vous n'ayez l'intention d'afficher votre code réel ici et ensuite marquer comme la réponse afin que les autres sachent ce que vous avez fait différemment afin qu'ils puissent apprendre aussi. Juste FYI. – jcolebrand

+0

Le commentaire ci-dessus explique comment je l'ai fait, avec EXACTEMENT le même code que dans la question d'origine, mais merci. – JamesStuddart

0

Vous n'avez pas inclus l'exception.Message mais selon la page MSDN pour NamedPipeServerStream, l'exception IOException est pour "Le nombre maximal d'instances de serveur a été dépassé." Est-ce l'exception que vous obtenez?

Si oui, qu'est-ce que numThreads est défini sur, et est-il possible que vous ayez une autre instance de votre application en cours d'exécution? (Par exemple, le test unitaire vous expérimentions?)

+0

J'ai inclus l'exception? le nombre max que j'ai défini est 10, et le tuyau n'est même pas créé, il bombarde juste après que je commence le service – JamesStuddart

+0

Etes-vous sûr que votre application de test ne fonctionne plus? Et, Vous avez inclus le type (IOException) de l'exception mais pas le message. –

+0

J'ai maintenant ajouté le code que j'utilise, est-ce que le battement de coeur fait tourner le batteur tout le temps? – JamesStuddart