-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; 它不会抓住它。这可能类似于ThreadAbortasp.net 的问题(但这只是一个猜测)。

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 回答