1. #1
    Membre régulier Avatar de nanooby
    Homme Profil pro
    IT Consultant
    Inscrit en
    mai 2014
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : IT Consultant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : mai 2014
    Messages : 103
    Points : 114
    Points
    114

    Par défaut Service WCF dans un service Windows

    Hello les amis

    J'aurais bien besoin d'un petit coup de main sur une appli que je développe.
    Je travaille sur un service Windows qui héberge un service WCF afin de pouvoir intéragir avec mon service Windows a partir d'une Api distante.
    Premier Windows service et aussi premier WCF service

    J'ai suivis quelques tutos pour en arriver ou j'en suis, plus particulierement ces deux la :
    https://docs.microsoft.com/en-us/dot...indows-service
    http://dotnetmentors.com/wcf/wcf-res...acontract.aspx

    Concernant le service WCF, j'ai créé une interface comme ci-dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    [ServiceContract]
        public interface ISharePointUploaderLocalAgentWCFService
        {
            [OperationContract]
            [WebGet(UriTemplate = "/AgentRunning", ResponseFormat = WebMessageFormat.Json)]
            bool AgentRunning();
     
            [OperationContract]
            [WebGet(UriTemplate = "/UploadsWatched", ResponseFormat = WebMessageFormat.Json)]
            List<SUPUpload> UploadsWatched();
     
            [OperationContract]
            [WebInvoke(UriTemplate = "/ModifiyUpload/{UploadId}", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "PUT")]
            SUPUpload ModifiyUpload(SUPUpload Upload, string UploadId);
     
            [OperationContract]
            [WebInvoke(UriTemplate = "/AddUpload", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST")]
            SUPUpload AddUpload(SUPUpload Upload);
     
            [OperationContract]
            [WebInvoke(UriTemplate = "/ModifyTimer/{Secondes}", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "PUT")]
            string ModifyTimer(string Secondes);
     
            [OperationContract]
            [WebInvoke(UriTemplate = "/RestartAgent", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST")]
            string RestartAgent();
     
            [OperationContract]
            [WebInvoke(UriTemplate = "/ScanSourceDirectory", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST")]
            string ScanSourceDirectory();
     
            [OperationContract]
            [WebInvoke(UriTemplate = "/EnableAgent", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "PUT")]
            string EnableAgent();
     
            [OperationContract]
            [WebInvoke(UriTemplate = "/DisableAgent", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "PUT")]
            string DisableAgent();
        }
    Et une classe service correspondante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        public class SharePointUploaderLocalAgentWCFService : ISharePointUploaderLocalAgentWCFService
        {
            public SharePointUploaderLocalAgentWCFService(List<SharePointUploaderFileSystemWatcher> watchers)
            {
                ...
            }
     
            private List<SharePointUploaderFileSystemWatcher> watchers = null;
     
            public List<SharePointUploaderFileSystemWatcher> Watchers
            {
                get { return watchers; }
                set { watchers = value; }
            }
     
            public bool AgentRunning()
            {
                ...
            }
     
            public List<SUPUpload> UploadsWatched()
            {
                ...
            }
     
            public SUPUpload ModifiyUpload(SUPUpload Upload, string UploadId)
            {
                  ...
            }
     
            public SUPUpload AddUpload(SUPUpload Upload)
            {
                ...
            }
     
            public string ModifyTimer(string Secondes)
            {
                ...
            }
     
            public string RestartAgent()
            {
                ...
            }
     
            public string ScanSourceDirectory()
            {
                ...
            }
     
            public string EnableAgent()
            {
                ...
            }
     
            public string DisableAgent()
            {
                ...
            }
    J'ai mis a jour mon fichier AppConfig avec le code suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <system.serviceModel>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
        <services>
          <service behaviorConfiguration="Default" name="SharePointUploaderLocalAgent.Services.SharePointUploaderLocalAgentWCFService">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000"/>
              </baseAddresses>
            </host>
            <endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="SharePointUploaderLocalAgent.Services.ISharePointUploaderLocalAgentWCFService" />
     
            <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
          </service>
        </services>
        <behaviors>
          <endpointBehaviors>
            <behavior name="webBehavior">
              <webHttp helpEnabled="true" />
            </behavior>
          </endpointBehaviors>
          <serviceBehaviors>
            <behavior name="Default">
              <serviceMetadata httpGetEnabled="true" />
            </behavior>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    NB: Un tuto utilise le port 8000, l'autre le port 61090. J'ai essayé avec les deux, sans succés.

    J'ai testé mon service Windows en application console, il tourne correctement, le service WCF est bien ouvert comme suit et conservé dans une variable de mon service Windows

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    protected override void OnStart(string[] args)
            {
                try
                {
                    ...
     
                    // Create a ServiceHost for the SharePointUploaderLocalAgentWCFService type 
                    serviceHost = new ServiceHost(new SharePointUploaderLocalAgentWCFService(watchers));
                    serviceHost.Open();
                }
                catch(Exception ex)
                {
                    Notifier myNotifier = new Notifier();
                    myNotifier.NotifyError(new Exception("An unexpected error occured while starting the service. ", ex));
                    Stop();
                }
            }
    J'ai donc installé mon service Windows, lancé le service, j'ai attaché le debugger au service, mais quand je tape l'adresse http://localhost:8000/UploadsWatched par exemple, mon point d'arret n'est pas atteint, et le browser ne peut pas afficher la page.

    Tout d'abord, concernant le fait que je n'atteigne pas mon service en local, j'aurais pensé a un problememe de réglage dans le fichier AppConfig. J'ai cherché mais je ne vois pas ce qui cloche. Si quelqu'un peut m'ouvrir les yeux, much appreciated

    Ensuite, j'ai du mal a voir comment mon Api pourrait accéder a mon service WCF sans qu'il ne soit déployé dans IIS. Quelqu'un pourrait-il m'éclaircir sur le sujet please? Des explications, un tuto peut-etre?

    Merci d'avance pour votre aide!
    PS : désolé pour les accents ou autres, clavier QWERTY, Scotland oblige

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    12 804
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 12 804
    Points : 23 040
    Points
    23 040

    Par défaut

    wcf peut être hébergé dans un exe classique (un service windows est un exe classique pour moi)
    tout est accessible de la même manière que quand c'est hébergé par IIS
    c'est le .open qui s'occupe de lancer ce qu'il faut pour que l'écoute fonctionne

    le mieux serait que tu commences par l'hébergement dans un projet console pour voir ce qu'il se passe, et ensuite passer sur le service
    moi je fais même un exe mixte dans ces cas là, à savoir si je démarre depuis vs, c'est une appli console, pratique à débugger, et si c'est depuis le démarrage du service windows alors ca passe par le onstart

    après il faut voir si le .open est bloquant ou pas, auquel cas il n'a rien à faire dans onstart
    et s'il ne l'est pas il faudrait vérifier que ton service ne s'arrête pas dans la foulée, d'ailleurs tu peux vérifier ça en premier, cliquer sur rafraichir dans la liste des services quelques secondes après le démarrage pour voir s'il tourne encore
    dans les faits
    - si on ne sort pas de onstart en quelques secondes, windows pense que le service bug donc il abandonne le démarrage
    - si à la sortir de onstart il n'y a aucun thread qui tourne le service s'arrête en pensant que c'est un arrêt normal
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre actif Avatar de joKED
    Profil pro
    Inscrit en
    février 2006
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : février 2006
    Messages : 285
    Points : 289
    Points
    289

    Par défaut

    A priori, si ton service windows démarre correctement, et reste démarré, il y a peut être une piste à creuser au niveau du compte utilisateur sur lequel tourne le service.

    Par exemple, si ton service utilise le compte "NETWORK SERVICE", il faut autoriser ce compte à "register" l'url de ton service wcf via une commande netsh du style (de mémoire) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    netsh http add urlacl url=http://+:8000/UploadsWatched user="NETWORK SERVICE"
    Tant va la cruche à l'eau qu'à la fin y'a plus d'eau.

  4. #4
    Membre régulier Avatar de nanooby
    Homme Profil pro
    IT Consultant
    Inscrit en
    mai 2014
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : IT Consultant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : mai 2014
    Messages : 103
    Points : 114
    Points
    114

    Par défaut

    Tout d'abord, merci d'avoir pris le temps de répondre.

    @Pol63, j'ai changé mon projet en application console le temps de faire des tests pour vérifier que le service se lance bien et passe par OnStart et OnStop correctement.
    J'ai essayé a partir de la, apres la sortie de OnStart, d'effectuer des tests sur le service WCF sans succes. J'ai donc repassé le projet en application Windows (service) et ai installé le service pour tester une fois en place.
    Je confirme que le service reste bien lancé et ne s'arrete pas.

    après il faut voir si le .open est bloquant ou pas
    Qu'entends tu par la?

    @joKED, le compte que j'utilise est le compte utilisateur de ma VM qui a les droits d'administration. Je vais essayer la commande et réinstaller mon service pour voir.

  5. #5
    Membre régulier Avatar de nanooby
    Homme Profil pro
    IT Consultant
    Inscrit en
    mai 2014
    Messages
    103
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : IT Consultant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : mai 2014
    Messages : 103
    Points : 114
    Points
    114

    Par défaut

    Donc, j'ai executé la commande de joKED et ca fonctionne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    netsh http add urlacl url=http://+:8000/ user=DOMAIN\User
    @joKED, as-tu plus de détails sur ce que fait cette commande? Pourquoi est-elle nécessaire?
    Avant le déploiement de la solution sur le serveur, sera t'il nécessaire d'executer la commande, peu importe le compte choisi?

  6. #6
    Membre actif Avatar de joKED
    Profil pro
    Inscrit en
    février 2006
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : février 2006
    Messages : 285
    Points : 289
    Points
    289

    Par défaut

    Salut,

    Voici la doc pour le pourquoi du comment de netsh : https://docs.microsoft.com/en-us/dot...http-and-https

    TL;DR > J'autorise l'utilisateur untel à recevoir les requêtes http sur l'adresse sur l'adresse/port spécifié
    Tant va la cruche à l'eau qu'à la fin y'a plus d'eau.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Evenements dans un service WCF
    Par Seth77 dans le forum Windows Communication Foundation
    Réponses: 23
    Dernier message: 23/05/2012, 12h52
  2. Avantages de hoster wcf dans un service windows
    Par LEK dans le forum Services Web
    Réponses: 7
    Dernier message: 05/10/2011, 17h33
  3. Asynchro dans un service WCF Duplex
    Par Z4ng3tsu dans le forum Services Web
    Réponses: 3
    Dernier message: 14/05/2010, 13h41
  4. SL3 : Appel de services WCF hébergés en service windows ou IIS
    Par maitredede dans le forum Silverlight
    Réponses: 8
    Dernier message: 31/08/2009, 23h22
  5. Récupération des résultats des méthodes dans un service WCF
    Par est09 dans le forum Windows Communication Foundation
    Réponses: 16
    Dernier message: 02/04/2009, 16h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo