2

インストールしたばかりの Windows サービスを開始したい。

ServiceBase[] ServicesToRun;
if (bool.Parse(System.Configuration.ConfigurationManager.AppSettings["RunService"]))
{
    ServicesToRun = new ServiceBase[] { new IvrService() };
    ServiceBase.Run(ServicesToRun);
}

IvrService コードは次のとおりです。

partial class IvrService : ServiceBase
{
    public IvrService()
    {
        InitializeComponent();

        Process myProcess;
        myProcess = System.Diagnostics.Process.GetCurrentProcess();

        string pathname = Path.GetDirectoryName(myProcess.MainModule.FileName);

        //eventLog1.WriteEntry(pathname);

        Directory.SetCurrentDirectory(pathname);

    }

    protected override void OnStart(string[] args)
    {
        string sProcessName = Process.GetCurrentProcess().ProcessName;

        if (Environment.UserInteractive)
        {
            if (sProcessName.ToLower() != "services.exe")
            {
                // In an interactive session.
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new IvrInteractive());
                IvrApplication.Start(); // the key function of the service, start it here
                return;
            }
        }
    }

サービスの開始方法がわかりません。使用ServiceController.Start()?中ですが、すでに持っていますServiceBase.Run(ServicesToRun);サービスを開始するためのものですか?

コードヒントは大歓迎です。

4

2 に答える 2

5

コードからサービスを開始することに関する質問に答えるには、次のようなものが必要です (net start myserviceコマンド ラインから実行するのと同じです)。

ServiceController sc = new ServiceController();
sc.ServiceName = "myservice";

if (sc.Status == ServiceControllerStatus.Running || 
    sc.Status == ServiceControllerStatus.StartPending)
{
    Console.WriteLine("Service is already running");
}
else
{
    try
    {
        Console.Write("Start pending... ");
        sc.Start();
        sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10));

        if (sc.Status == ServiceControllerStatus.Running)
        {
            Console.WriteLine("Service started successfully.");
        }
        else
        {
            Console.WriteLine("Service not started.");
            Console.WriteLine("  Current State: {0}", sc.Status.ToString("f"));
        }
    }
    catch (InvalidOperationException)
    {
        Console.WriteLine("Could not start the service.");
    }
}

これによりサービスが開始されますが、上記のコードを実行しているプロセスとは異なるプロセスになることに注意してください。


ここで、サービスのデバッグに関する質問に答えます。

  • 1 つのオプションは、サービスの開始後にアタッチすることです。
  • もう 1 つは、サービスの実行可能ファイルを、サービスとしてではなく、通常の実行可能ファイルとして実行できるようにすることです (通常は、コマンド ライン パラメーターを使用してセットアップします)。その後、IDE から F5 キーを押すことができます。


編集:イベントのサンプルフローを追加(コメントのいくつかからの質問に基づく)

  1. OSはサービスの開始を求められます。これは、コントロール パネル、コマンド ライン、API (上記のコードなど) から、または OS によって自動的に (サービスのスタートアップ設定に応じて) 実行できます。
  2. 次に、オペレーティング システムが新しいプロセスを作成します。
  3. 次に、プロセスはサービス コールバックを登録します (たとえばServiceBase.Run、C# またはStartServiceCtrlDispatcherネイティブ コードで)。そして、そのコードの実行を開始します (ServiceBase.OnStart()メソッドを呼び出します)。
  4. その後、OS はサービスの一時停止、停止などを要求できます。その時点で、OS は既に実行中のプロセスに制御イベントを送信します (ステップ 2 から)。これにより、ServiceBase.OnStop()メソッドが呼び出されます。


編集: サービスを通常の実行可能ファイルまたはコマンド ライン アプリとして実行できるようにする: 1 つの方法は、アプリをコンソール アプリケーションとして構成し、コマンド ライン スイッチに基づいて別のコードを実行することです。

static void Main(string[] args)
{
    if (args.Length == 0)
    {
        // we are running as a service
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] { new MyService() };
        ServiceBase.Run(ServicesToRun);
    }
    else if (args[0].Equals("/debug", StringComparison.OrdinalIgnoreCase))
    {
        // run the code inline without it being a service
        MyService debug = new MyService();
        // use the debug object here
    }
于 2013-10-02T15:48:39.177 に答える
0

まず、InstallUtil を使用してサービスをインストールする必要があります。

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe C:\MyService.exe

コマンドラインからサービスを開始する必要があります。

net start ServiceName // whatever the service is called

次に、[ツール] > [プロセスにアタッチ] を使用して、Visual Studio でプロセスにアタッチする必要があります。

ソリューションを中断したい場所にブレークポイントを設定すると、開発環境が引き継ぐ必要があります。

開発環境から開始するには、net start ServiceNameコマンドをバッチ ファイルに入れ、[プロジェクト プロパティ] > [ビルド イベント] の [ビルド イベント後のコマンド ライン] で、バッチ ファイルへのパスを追加できます。

*今見てみると、バッチファイルを使用する必要があるかどうかはわかりませんが、そこにコマンドを直接入れることができるかもしれません. この回答を編集してみてください。

于 2013-10-02T15:26:35.053 に答える