Wait for service.InvokeMethod to finish - WMI, C#

2019-09-11 13:42发布

问题:

i'm stoppinga service on remote machine with WMI:

    protected override void Execute()
    {
        ConnectionOptions connectoptions = new ConnectionOptions();
        connectoptions.Username = RemoteMachineUsername;
        connectoptions.Password = RemoteMachinePassword;

        ManagementScope scope = new ManagementScope(@"\\" + RemoteMachineName + @"\root\cimv2");
        scope.Options = connectoptions;
        SelectQuery query = new SelectQuery("select * from Win32_Service where name = '" + ServiceName + "'");
        using (ManagementObjectSearcher searcher = new
                    ManagementObjectSearcher(scope, query))
        {
            ManagementObjectCollection collection = searcher.Get();

                foreach (ManagementObject service in collection)
                {
                    if (service.GetPropertyValue("State").ToString().ToLower().Equals("running"))
                    {
                        //Stop the service
                        service.InvokeMethod("StopService", null);//HOW TO WAIT FOR THIS TO FINISH?
                    }
                }
        }
    }

now, this method finished long before the service is stopped. my question is, how can i wait for the service to be stopped and how can i know if it succeeded. in other words, i want to do this in a sync way.

thanks!

回答1:

StopService returns a uint status code you you can cast the result of your InvokeMethod all to an uint and check its return value.

The call already should be synchronous, but it could be timing out if the service doesn't respond to the stop request immediately. If that is the case you could always loop on checking the service State property.



回答2:

The ManagementObject.InvokeMethod Method does not execute synchronously, it is asynchronous.

You could parse the out parameters for the process id:

//Execute the method
ManagementBaseObject outParams = 
processClass.InvokeMethod("Create", inParams, null);

//Display results
//Note: The return code of the method is provided
// in the "returnValue" property of the outParams object
Console.WriteLine("Creation of calculator " +
    "process returned: " + outParams["returnValue"]);
Console.WriteLine("Process ID: " + outParams["processId"]);

And from there wait for the process to complete, via some form of polling. Word of caution though, if your process does not complete and exit, you may be waiting for a while. There may be a better solution - I am currently looking into this myself as well.



标签: c# wmi