Tray Notify - Part III (WCF Service) | CodeGuru

Tray Notify – Part III (WCF Service)

1. Introduction This is the third part of the Tray Notify series which illustrates how a Windows client app can communicate with a Window Service. The sample application monitors file change events from the Windows service and uses a WCF service to send the change events to a task bar tray application. This article will […]

Written By
CodeGuru Staff
CodeGuru Staff
Sep 1, 2010
4 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

1. Introduction

This is the third part of the Tray Notify series which illustrates how a Windows client app can communicate with a Window Service.

The sample application monitors file change events from the Windows service and uses a WCF service to send the change events to a task bar tray application.

This article will walk through the creation of the WCF service and how to host it inside the Windows Service that was created in Part II.


  • Part I – Covers the basic architecture and the creation of the common class library.

  • Part II – Covers the creation of the Windows Service and service installer using C#.

  • Part III – Covers the creation of the WCF service and how it’s hosted inside the Windows Service.

  • Part IV- Covers the WPF tray application and its communication with the WCF service.

  • 2. WCF Overview

    A complete overview of WCF Services beyond the scope of this article but essentially WCF Services is Microsoft’s newer approach to creating Web Services. Earlier asmx Web Services (.net 2.0 and before) relied on IIS for hosting. With WCF services introduced in .Net 3.0, Microsoft has removed the IIS hosting restriction and has enabled WCF services to be hosted in any application including IIS, a Windows Service, or a .Net console, Winforms or WPF application.

    In addition, WCF offers bindings that allow different communication protocols such as http, TCP/IP and msmq to be used. WCF offers additional security options as well.

    For further information on WCF Service, see the Reference section at the end of this article.

    Advertisement

    3. Why use a WCF service as the communication layer?

    A WCF service was chosen as the communication layer between the Windows Service and the client Tray application because it offers two-way communication and it can be hosted from a Windows Service application. The client application calls a WCF service method to register itself with the service, and the service uses the dual binding to send notifications back to the client. In addition, WCF services are not session dependent so they are able to provide the communication layer between the Windows service running in session 0 and an interactive process running in a logged on user session (n).

    4. Build out the WCF Service

    Starting with the source code built in Part II, we are going to create a couple of WCF service interfaces as well as the code that monitors the file change events. The first interface will be the interface used by the client applications to registering themselves with the service on startup. This lets the WCF know where to send the file change notification events. The second interface is the callback event interface that passes the file change notification events to the clients.

    4.1 Create the TrayNotify Interface


    4.1.1 Remove the default Service files

    Remove the Service1 files from the CG.TrayNotify.WCF.Service project. By default, Visual Studio always adds this interface to a WCF Service project. Since we’ll be adding our own interface, we can delete the files related to this interface.


    1. Load the CG.TrayNotify solution created in Part II

    2. Expand the CG.TrayNotify.WCF.Service project in the solution explorer.

    3. Delete the Service1.cs file

    4. Delete the IService1.cs file

    5. Open the App.config file and remove the entries between the <system.ServiceModel/> nodes.

    6. Since we’ll be hosting this WCF Service in the Windows Service application, you can remove the <system.web/> nodes.

    You should be left with the following app.config entries:

    <?xml version=”1.0″ encoding=”utf-8″ ?>
    <configuration>
      <system.serviceModel>
      </system.serviceModel>
    </configuration>
    


    1.1.2 Create a ITrayNotify Interface

    The ITrayNotify interface is used by the client application to register itself with the service.


    1. Right click on the CG.TrayNotify.WCF.Service project in the Solution Explorer.

    2. Choose, “New Item”

    3. Under “Templates:”, choose “WCF Service”

    4. Change the name to “TrayNotify.cs”

    5. Click “Add”

    1.1.3 Modify the app.config file

    The app.config file will contain the new ITrayNotify service config entries. Modify the app.config file as follows:


    1. Within the “serviceBehaviors/behavior” node, rename the “CG.TrayNotify.Wcf.Service.TrayNotifyBehavior” name attribute to “TrayNotifyBehavior”.

    2. In the “services/service” node, do the following:


      • Change the behaviorConfiguration entry to “TrayNotifyBehavior”.

      • Change the name attribute from “CG.TrayNotify.Wcf.Service.TrayNotify” to “CG.TrayNotify.Wcf.Service:CG.TrayNotify.Wcf.TrayNotify”.

        Notice how the name contains a ‘:’. The left side of the colon contains the assembly name of the class contained on the right side. This isn’t a standard WCF services naming convention; however, this format will be used by the WcfServiceHost class which was added to the CG.TrayNotify.Common library in Part I.



    3. In the “services/service/endpoint” node, do the following:


      • Change the binding attribute to “wsDualHttpBinding”. Dual binding will enable the WCF Service to make calls to the client application. More on this later in Part IV.

      • Change the contract attribute to “CG.TrayNotify.Common.Interface.ITrayNotify”.

        Note: at present the ITrayNotify interface is not located in the CG.TrayNotify.Common class library; however, we will move it to the common library later.



    4. In the “services/service/endpoint/host” node, change the baseAddress attribute to “http://localhost:8071/TrayNotify”

    The completed app.config file should resemble:

    <configuration>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name=”TrayNotifyBehavior”>
              <serviceMetadata httpGetEnabled=”true” />
              <serviceDebug includeExceptionDetailInFaults=”false” />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service behaviorConfiguration=”TrayNotifyBehavior”
           name=”CG.TrayNotify.Wcf.Service:CG.TrayNotify.Wcf.Service.TrayNotifyEndpoint”>
            <endpoint address=””
              binding=”wsDualHttpBinding”
              contract=”CG.TrayNotify.Common.Interface.ITrayNotify”>
              <identity>
                <dns value=”localhost” />
              </identity>
            </endpoint>
            <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” />
            <host>
              <baseAddresses>
                <add baseAddress=”http://localhost:8071/TrayNotify/” />
              </baseAddresses>
            </host>
          </service>
        </services>
      </system.serviceModel>
    </configuration>
    

    1.1.4 Add the interface methods and callback interface

    Open the ITrayNotify.cs file and modify the default interface.


    1. Add attribute parameters to the ServiceContract attribute


      • Add the SessionMode = SessionMode.Required

      • Add the CallbackContract = typeof( ITrayNotifyCallback )


    2. Add the Register, Unregister, Start and Stop methods

    3. Create the ITrayNotifyCallback interface and method

    The complete ITrayNotify and ITrayNotifyCallback interfaces should look like:

        [ServiceContract( SessionMode = SessionMode.Required, CallbackContract = typeof( ITrayNotifyCallback ) )]
        public interface ITrayNotify
        {
            [OperationContract]
            void Register( Guid instanceId );
            [OperationContract]
            void UnRegister( Guid instanceId );
            [OperationContract]
            void Start( Guid instanceId, string folderToMonitor );
            [OperationContract]
            void Stop( Guid instanceId, string folderToMonitor );
        }
        [ServiceContract]
        public interface ITrayNotifyCallback
        {
            [OperationContract]
            void OnFileChangeEvent( FileEventArgs e );
        }
    



    WCF Service comment

    Setting the SessionMode parameter to Required forces WCF to retain session state between service calls. This is necessary in order to retain the connection to the ITrayNotifyCallback interface which gets registered when the client first connects to the server.

    CodeGuru Logo

    CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

    Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

    Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.