Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am running the following line to get a list of all services for a given computer:

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

If I run this on the main thread and pass in a computer name that exists but I don't have permissions to view the services for, such as:

ServiceController.GetServices("OtherComp"); 

InvalidOperationException:
Cannot open Service Control Manager on computer 'OtherComp'. This operation might require other privileges.

I fully expect this to happen. However my issue comes with running this on a background thread. Take this fully complete console program:

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
            }
        }
    }
}

I would expect an exception to be thrown, but as soon as the code tries to execute this line, it bails out of the thread.

I can't wrap the line in a trycatch; it will won't catch it. This might be simmilar to ThreadAbort problems with asp.net (but that is just a guess).

The msdn page on the ServiceController Class says that the static function is thread safe, however, a commenter on the function's msdn page says that it is not.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
141 views
Welcome To Ask or Share your Answers For Others

1 Answer

Exception was catched by BackgroundWorker internally, you can view it via RunWorkerCompleted event:

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: However, it works as expected with Thread class:

new Thread(() =>
    {
        try
        {
            var services = ServiceController.GetServices("OtherComputer");
        }
        catch
        {
        }
    }).Start();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...