-1

次の行を実行して、特定のコンピューターのすべてのサービスのリストを取得しています。

ServiceController[] services = ServiceController.GetServices(compName);

これをメイン スレッドで実行し、存在するが次のようなサービスを表示する権限がないコンピューター名を渡す場合:

ServiceController.GetServices("OtherComp"); 

InvalidOperationException:
コンピューター 'OtherComp' でサービス コントロール マネージャーを開けません。この操作には、他の権限が必要になる場合があります。

私はこれが起こることを完全に期待しています。ただし、これをバックグラウンド スレッドで実行すると問題が発生します。次の完全なコンソール プログラムを見てください。

using System.ComponentModel;
using System.ServiceProcess;

namespace ServiceTesting
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            ServiceAccessor sa = new ServiceAccessor();
            sa.Run();
        }
    }

    public class ServiceAccessor
    {
        BackgroundWorker bw;

        public ServiceAccessor()
        {
            bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new
                RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }

        public void Run()
        {
            bw.RunWorkerAsync();
        }

        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            //this line is where the bail happens
            var services = ServiceController.GetServices("OtherComputer");
        }

        void bw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
        {
            // the code will never get to this method
            if (e.Error != null)
            {
                //something
            }
        }
    }
}

例外がスローされることを期待しますが、コードがこの行を実行しようとするとすぐに、スレッドから抜け出します。

try\catch行を;で囲むことはできません。それはそれをキャッチしません。これは、asp.net の問題に似ている可能性がありますThreadAbort(ただし、これは単なる推測です)。

ServiceController クラスのmsdn ページには、静的関数はスレッド セーフであると記載されていますが、関数の msdn ページのコメント作成者は、そうではないと述べています。

4

1 に答える 1

1

例外は BackgroundWorker によって内部的にキャッチされました。RunWorkerCompleted イベントを介して表示できます。

private void backgroundWorker1_RunWorkerCompleted(
    object sender, RunWorkerCompletedEventArgs e)
{
    // First, handle the case where an exception was thrown. 
    if (e.Error != null)
    {
        // deal with error
    }
}

http://msdn.microsoft.com/en-us/library/system.componentmodel.runworkercompletedeventargs.aspx

UPD: ただし、 Thread クラスでは期待どおりに動作します:

new Thread(() =>
    {
        try
        {
            var services = ServiceController.GetServices("OtherComputer");
        }
        catch
        {
        }
    }).Start();
于 2013-11-05T16:50:21.357 に答える