使用 WCF 在 Windows 服务中管理带加密的设置






4.50/5 (3投票s)
一个简单的示例,演示如何使用 WCF 在 Windows 服务中管理设置。
引言
本文的目标是提供一个简单的示例,演示如何使用 WCF 在 Windows 服务中管理设置。
我最初尝试解决这个问题的方法是开发一个小型的 Windows Forms 应用程序,直接编辑服务 EXE 配置文件。我最终发现让服务本身处理设置保存,并在其中提供一个小的 WCF 服务来暴露功能给我的 Windows Forms 应用程序,这要优雅得多。
顺便说一句:这是我的第一篇文章,为我的粗糙的英语道歉...
背景
这段代码使用了非常基础的 WCF 服务实现。对于那些从未用过 WCF 的人,我推荐我开始学习的书籍:Microsoft Windows Communication Step By Step,由微软出版社出版,约翰·夏普 (John Sharp) 编写。
使用代码
该演示由三个项目组成
- SampleService,它实现了 Windows 服务和 WCF 服务。
- SettingsApplication,它实现了用于使用
PropertyGrid
控件管理设置的表单应用程序。 - SampleServiceSetup,是用于安装服务和设置应用程序的安装项目。
示例服务在 IAppSettingsService.cs 中暴露了一个简单的 WCF 服务契约
[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; }
}
AppSettingsService.cs 中的契约实现提供了 GetSettings
和 SetSettings
方法。SetSettings
方法使用 RsaProtectedConfigurationProvider
加密设置。
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");
}
}
...
在客户端应用程序侧,我定义了一个 ClientServiceSettings
类,以提供其他信息,并可能为 PropertyGrid
提供自定义编辑器
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; }
}
然后,从客户端应用程序检索设置就像这样简单
using (var client = new AppSettingsServiceClient())
{
set = new ClientServiceSettings(client.GetSettings());
propertyGrid1.SelectedObject = set;
}
就这样了。我希望我的这些微薄的贡献对您有所帮助。祝您编码愉快!