4

別のプログラムを介して制御したいサービスを作成しました(サーバーの1つで実行します)。私はサービスに少し問題がありますが、誰かが助けてくれることを願っています。

以下のルートを使用してサービスを制御しようとすると、サーバー上にいるユーザーに対してのみ機能します。

ServiceController service = new ServiceController("MyService", "MyServer");

try
{
    if (service.Status == ServiceControllerStatus.Running)
    {
        teServiceStatus.BackColor = Color.LightGreen;
        teServiceStatus.Text = "Running";
        sbStartService.Enabled = false;
        sbStopService.Enabled = true;
    }
    else
    {
        teServiceStatus.BackColor = Color.Red;
        teServiceStatus.Text = "Stopped";
        sbStartService.Enabled = true;
        sbStopService.Enabled = false;
    }
}
catch (InvalidOperationException ioe)
{
    if (System.Diagnostics.Debugger.IsAttached)
        System.Diagnostics.Debugger.Break();
    else
    {
        teServiceStatus.Text = "Cannot Connect";
        teServiceStatus.BackColor = Color.Red;
    }
}
catch (Exception ex)
{
    if (System.Diagnostics.Debugger.IsAttached)
        System.Diagnostics.Debugger.Break();
    else
        ;
}

したがって、ネットワークユーザーとして、私はユーザーとしてサーバー上にいて、このサービスを制御するプログラムを実行すると、ステータスを確認して開始および停止できますが、他のユーザーはできません(サーバー、私はやりたくない)。

以下のルートを使用して、サーバー上のユーザーになりすますこともできます。

//Establish connection to the Publishing Server with application credentials.
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
connectionOptions.EnablePrivileges = true;
connectionOptions.Username = "UserOnServer";
connectionOptions.Password = "UserPassword";
ManagementScope managementScope = new ManagementScope(@"\\MyServer\root\cimv2", connectionOptions);
managementScope.Connect();

ManagementPath path = new ManagementPath("Win32_Service");
ManagementClass services = new ManagementClass(managementScope, path, null);

foreach (ManagementObject service in services.GetInstances())
{
    try
    {
        if (service.GetPropertyValue("Name").ToString() == "MyService")
            if (service.GetPropertyValue("State").ToString().ToLower().Equals("running"))
            {
                teServiceStatus.BackColor = Color.LightGreen;
                teServiceStatus.Text = "Running";
                sbStartService.Enabled = false;
                sbStopService.Enabled = true;
            }
            else
            {
                teServiceStatus.BackColor = Color.Red;
                teServiceStatus.Text = "Stopped";
                sbStartService.Enabled = true;
                sbStopService.Enabled = false;
            }
    }
    catch (InvalidOperationException ioe)
    {
        if (System.Diagnostics.Debugger.IsAttached)
            System.Diagnostics.Debugger.Break();
        else
        {
            teServiceStatus.Text = "Cannot Connect";
            teServiceStatus.BackColor = Color.Red;
        }
    }
    catch (Exception ex)
    {
        if (System.Diagnostics.Debugger.IsAttached)
            System.Diagnostics.Debugger.Break();
        else
        {
            teServiceStatus.Text = "Cannot Connect";
            teServiceStatus.BackColor = Color.Red;
        }
    }
} 

これは、プログラムを使用するすべてのユーザーがサービスを開始/停止して現在のステータスを確認できるように機能しますが、プログラムが終了すると、サービスは停止します(それが発生するかどうかはわかりませんが、発生します)。

では、プログラムを使用する人がプログラムを開始、停止、およびサービスステータスを読み取るにはどうすればよいですか?身近に感じますが、どうやら何かが足りないようです。

更新 ConnectionOptionsルートを使用する場合、ConnectionOptions(またはManagementScope)が入っているフォームが閉じられるとすぐに表示され、ログインしたユーザーが「ログオフ」したため、サーバーはそれを記録し、その時点でサービスをシャットダウンします。時間。理由はわかりませんが、それでも調査しようとしています。

4

1 に答える 1

0

実行中のクライアントコードにアカウントを偽装NT AUTHORITY\NetworkServiceさせて、サービスと同じレベルの権限を持つようにします。そのアカウントのパスワードはnullです(または空の文字列です。両方試してみてください)。そのユーザーを偽装しながらコードを実行する方法に関するドキュメントは、WindowsIdentity.Impersonateに示されています。なりすまし/委任に関する詳細はこちら。

また、サービス内の未処理のすべての例外のハンドラーを実装することもできます。try / catchブロックの外部で例外がスローされている可能性があります。そのため、接続されているデバッガーがcatchブロックに設定されているブレークポイントを壊さずにアプリケーションを終了しています。

于 2012-07-09T20:20:41.100 に答える