次の行を実行して、特定のコンピューターのすべてのサービスのリストを取得しています。
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 ページのコメント作成者は、そうではないと述べています。