Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

Managing settings with encryption in a Windows Service using WCF

4.50/5 (3 votes)
2 Apr 2009CPOL1 min read 21.4K   192  
A simple example of a method to manage settings in a Windows Service using WCF.

wcfmanagedsetting2.jpg

Introduction

The goal of this article is to provide a simple example of a method to manage settings in a Windows Service using WCF.

My first attempt to solve this situation was to develop a small Windows Dorms application which would directly edit the service EXE config file. I finally found it much more elegant to let the service itself deal with the settings savings, and provide a small WCF service inside of it to expose functionalities to my Windows Forms application.

P.S.: this is my first article, and I apologize for my rough English...

Background

This code makes use of a very basic implementation of a WCF Service. For those who have never used WCF, I would recommend the book with which I started: Microsoft Windows Communication Step By Step published by Microsoft Press and written by John Sharp.

Using the code

The demo is composed of three projects:

  • SampleService, which implements the Windows Service and the WCF Service.
  • SettingsApplication, which implements the forms app which manages the settings with a PropertyGrid control.
  • SampleServiceSetup, which is the setup project to install the Service and the Settings application.

The sample service exposes a simple WCF service contract in IAppSettingsService.cs:

C#
[ServiceContract]
public interface IAppSettingsService
{
    [OperationContract]
    ServiceSettings GetSettings();
    [OperationContract]
    void SetSettings(ServiceSettings set);
}
[DataContract]
public class ServiceSettings
{
    [DataMember]
    public String Host { get; set; }
    [DataMember]
    public int Port { get; set; }
    [DataMember]
    public String User { get; set; }
    [DataMember]
    [PasswordPropertyText(true)]
    public String Password { get; set; }
}

The contract implementation in AppSettingsService.cs provides the GetSettings and SetSettings methods. The SetSettings method encrypts the settings using RsaProtectedConfigurationProvider :

C#
public ServiceSettings GetSettings()
{
    try
    {
        return new ServiceSettings
        {
        Host = Settings.Default.Host,
        Password = Settings.Default.Password,
        Port = Settings.Default.Port,
        User = Settings.Default.User
        };
    }
    catch (Exception err)
    {
        throw GetErrMessage(err, "GetSettings");
    }
}
public void SetSettings(ServiceSettings set)
{
    Type type = set.GetType();
    try
    {
        var config = 
          ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        var section = (ClientSettingsSection)
            config.GetSection("applicationSettings/SampleService.Settings");
        if (section.SectionInformation.IsProtected)
            section.SectionInformation.UnprotectSection();
        foreach (SettingElement t in section.Settings)
        {
            var propertyInfo = type.GetProperty(t.Name);
            t.Value.ValueXml.InnerText = propertyInfo.GetValue(set, null).ToString();
        }
        if (!section.SectionInformation.IsProtected)
            section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
        section.SectionInformation.ForceSave = true;
        config.Save(ConfigurationSaveMode.Full);
        Settings.Default.Reload();
    }
    catch (Exception err)
    {
        throw GetErrMessage(err, "SetSettings");
    }
}
...

On the client application side, I defined a ClientServiceSettings class to provide additional information and possibly custom editors for the PropertyGrid:

C#
public class ClientServiceSettings
{
    public ClientServiceSettings(ServiceSettings settings)
    {
        Host = settings.Host;
        Port = settings.Port;
        User = settings.User;
        Password = settings.Password;
    }
    [DisplayName("Host")]
    [Category("Server")]
    [Description("Enter the host name or IP address.")]
    public String Host { get; set; }
    [DisplayName("Port Number")]
    [Category("Server")]
    [Description("Enter the port number.")]
    public int Port { get; set; }
    [DisplayName("User")]
    [Category("Credentials")]
    [Description("User login to access server.")]
    public String User { get; set; }
    [DisplayName("Password")]
    [Category("Credentials")]
    [PasswordPropertyText(true)]
    [Description("The user's password. It will be encrypted " + 
                 "in the configuration settings file.")]
    public String Password { get; set; }
}

Then, retrieving the settings from the client application is as simple as:

C#
using (var client = new AppSettingsServiceClient())
{
    set = new ClientServiceSettings(client.GetSettings());
    propertyGrid1.SelectedObject = set;
}

That's it. I hope some of you will find this modest contribution useful. Cheers and happy coding!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)