Windows サービスは、最初は次のようになります。
using System.ServiceProcess;
internal partial class MyService : ServiceBase
{
static void Main()
{
ServiceBase[] ServicesToRun = new ServiceBase[] { new MyService() };
ServiceBase.Run( ServicesToRun );
}
}
私が行ったことは、Main()
次のように、サービスの起動とコマンドラインの処理の両方に使用できるように変更することです。
using System;
using System.Runtime.InteropServices;
using System.ServiceProcess;
internal partial class MyService : ServiceBase
{
const int ATTACH_PARENT_PROCESS = -1;
[DllImport( "kernel32.dll" )]
static extern bool AttachConsole( int dwProcessId );
[DllImport( "kernel32.dll" )]
static extern bool FreeConsole();
static void Main()
{
if ( Environment.UserInteractive ) {
try {
// Redirect console output to the parent process.
AttachConsole( ATTACH_PARENT_PROCESS );
// Process command line arguments here...
} catch {
// Handle exceptions here...
} finally {
// Detach from the console.
FreeConsole();
}
} else {
ServiceBase[] ServicesToRun = new ServiceBase[] { new MyService() };
ServiceBase.Run( ServicesToRun );
}
}
}
実行可能ファイルがビルドされたら、通常どおりオペレーティング システムに登録します (実際には、-install コマンド ライン オプションを使用して登録します)。サービスが開始されると、UserInteractive
フラグはfalseであるため、サービスは通常どおり開始されます。ただし、コマンド プロンプトからはUserInteractive
フラグがtrueであるため、コマンド ライン処理が引き継ぎます。
この時点で必要なのは、実行可能ファイルのコマンドライン インスタンスが、ある種の IPC (ソケット、パイプ、共有メモリ、WCF など) を介して実行可能ファイルのサービス インスタンスと通信することだけです。