我正在运行以下行来获取给定计算机的所有服务的列表:
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
问题相似(但这只是猜测)。
msdn page on the ServiceController Class表示静态函数是线程安全的,但function's msdn page上的评论者说它不是。
答案 0 :(得分: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();