ADO.NET2.0にて、新たに追加されているTransactionScope等を使用する場合
MS-DTCサービスが起動していないとエラーとなります。
でも、実際にアプリを配布する対象のマシンのサービスを起動してくださいって
頼むのも大変ですので、アプリが動いている間だけ起動しておいてほしいな
って感じですね。てことで、ちょろっと作ってみました。
めっちゃ簡素な作りになっていますがご勘弁を。一応、個人的には使えているので
オッケイかなとw
Permission周りとか全然考慮していませんので、権限が弱いと多分エラーでます。w
以下のような感じです。
using System; using System.ServiceProcess; namespace Gsf.Lib.ServiceControl { ////// MS-DTCサービスの起動と終了を管理するクラスです。 /// ////// 本クラスは、ADO.NET2.0のトランザクション機能を利用する為に必要なMS-DTCサービスの /// 起動・終了を管理します。 /// /// Startメソッドで開始。Stopメソッドで停止します。 /// /// 前提条件として、以下の事柄が存在します。 /// (1) 既に起動している場合は何もしません。 /// (2) 停止処理は、開始する前の状態が停止処理であった場合のみ行われます。 /// (つまり、元の状態に戻します。) /// (3) 開始・停止以外のステータスには対応していません。 /// /// 本クラスは、IDisposableインターフェースを実装していますので /// usingブロックにて使用できます。その際、ブロックを抜けるときに /// Stopメソッドがコールされます。 /// /// 以下、利用例です。 /// public class MSDTCServiceController : IServiceController, IDisposable { ////// using(MSDTCServiceController serviceController = new MSDTCServiceController()){ /// 処理..... /// } /// ////// サービス名 /// const string SERVICE_NAME = "MSDTC"; ////// 元々のサービスの状態 /// ////// 初期値はデフォルトで停止状態でセットされています。 /// protected ServiceControllerStatus _initialStatus = ServiceControllerStatus.Stopped; ////// 停止処理が既に行われているか否か。 /// protected bool _isStopped = false; ////// デフォルトコンストラクタ /// ////// 自動起動モードをONにして、クラスを構築します。 /// public MSDTCServiceController() : this(true) { // nop; } ////// コンストラクタ /// ////// 自動起動を行うか否かを指定できるコンストラクタです。 /// /// 自動起動を行うか否か public MSDTCServiceController(bool autoStartUp) { if(autoStartUp) { Start(); } } ////// サービスを開始します。 /// ////// 元々の状態が停止状態の場合のみ、サービス起動を行います。 /// public void Start() { using(ServiceController service = new ServiceController(SERVICE_NAME)) { if*1 { if(service.Status == ServiceControllerStatus.Running) { service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped); _isStopped = true; } } } } ////// データの破棄処理を行います。 /// ////// このメソッドは、内部でStopメソッドを呼び出します。 /// /// Stopメソッドが呼ばれる条件は以下の通りです。 /// (1) まだ、Stopメソッドが呼ばれていない場合 /// public void Dispose() { if(!_isStopped) { Stop(); } } } }
使い方としては、usingブロックで囲って使うのが一番簡単です。
using(MSDTCServiceController sc = new MSDTCServiceController()){ xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx }
みたいな感じで。
【追記】
上記のクラスをユーザグループがPowerUserのユーザで実行すると、起動はできるけど停止が出来ないです・・・・。
admin権限がやっぱり必要??
*1:_initialStatus = service.Status) == ServiceControllerStatus.Stopped) {
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running);
}
}
}
///