WindowsサービスプログラムでXMLを設定ファイルとして使用する方法を実装してみた。
- ここではWindowsサービスの設定方法の詳細は割愛するが、インストーラーを追加する際、「Account」は「LocalSystem」にする(デフォルトは「User」)。
- プロパティ→ビルドアクションを「埋め込みリソース」にする。ここが重要で、Windowsサービスプログラムだとこの設定でないとxmlファイルを使用することができない。
####3.サービス処理の実装
3.1.デシリアライズ用のメソッド
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
namespace WinServiceAppSample1 {
public class LoadXML {
public static T Load<T>(Stream stream) where T : new() {
T result = default(T);
var serializer = new DataContractSerializer(typeof(T));
using(var reader = XmlReader.Create(stream)) {
result = (T)serializer.ReadObject(reader);
}
return result;
}
}
}
3.2.デシリアライズ対象オブジェクトのためのクラス
using System.Runtime.Serialization;
namespace WinServiceAppSample1 {
[DataContract(Name = "root")]
public class ObjSetting {
[DataMember(Name = "settings")]
public Settings settings {
get;private set;
}
}
[DataContract(Name = "settings")]
public class Settings {
[DataMember(Name = "save-dir")]
public string SaveDir {
get; private set;
}
[DataMember(Name = "save-log")]
public string SaveLog {
get; private set;
}
}
}
- ここまでは、普通のDataContractSerializerを使用したxmlのデシリアライズと同様の方法だが、埋め込みリソースにしているxmlファイルをStreamクラスに変換させる必要がある。これは「Assembly」クラスを使用して実装する。
3.3.埋め込みリソースをStreamクラスに変換してデシリアライズ
using System.Reflection;
using System.IO;
namespace WinServiceAppSample1 {
public class Execute {
public void LoadXml() {
//【重要】xmlファイル名を指定する場合は「プロジェクト名.File1.xml」という形式にする必要がある
var xmlfile = "WinServiceAppSample1.XMLSettingFile.xml";
var assembly = Assembly.GetExecutingAssembly();
var assxml = assembly.GetManifestResourceStream(xmlfile);
var objsetting = LoadXML.Load<ObjSetting>(assxml);
using(var sw = new StreamWriter(Path.Combine(objsetting.settings.SaveDir, objsetting.settings.SaveLog),true)) {
sw.WriteLine(System.DateTime.Now);
}
}
}
}
- コードにも記載しているが、xmlファイル名は「プロジェクト名.File1.xml」という形式にする必要がある。別フォルダにある場合は、「プロジェクト名.HOGE_DIR.File1.xml」となる。
単体テスト
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WinServiceAppSample1;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace WinServiceAppSample1.Tests {
[TestClass()]
public class ExecuteTests {
[TestMethod()]
public void LoadXmlTest() {
//Arrange
var filename = @"C:\temp\hoge.log";
File.Delete(filename);
//Act
var exec = new Execute();
exec.LoadXml();
//Asset
Assert.AreEqual(File.Exists(filename), true);
}
}
}
3.5.OnStartの実装
Windowsサービスの実装方法の詳細は割愛する。以下コードのみを記載。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace WinServiceAppSample1 {
public partial class SvcAppSample1 : ServiceBase {
private Timer timer;
public SvcAppSample1() {
InitializeComponent();
}
protected override void OnStart(string[] args) {
timer = new Timer(10000);
timer.Elapsed += (s, e) => {
new Execute().LoadXml();
};
timer.AutoReset = true;
timer.Start();
}
protected override void OnStop() {
timer.Stop();
}
}
}
####4.サービスのインストール
- 「installutil」コマンドを使用してサービスをインストールする。「VisualStudio 2015」フォルダから「開発者コマンドプロンプト for 2015」を「管理者として実行」する(「管理者として実行」をしないと、インストール時にエラーになる)。
サービスを開始すると、xmlで設定したフォルダにファイルが作成され、時間間隔で時刻が書かれていると思います。
以上です。