Forum Discussion

sergi's avatar
sergi
Contributor
6 years ago

How to properly start a Windows service

My app under test has a Windows service that I need to start at the beginning of the test if it is not already started.

I haven't found a way to do it in TestLeft API, so I am calling "sc.exe" directly with the following command:

 

 

this.driver.Applications.Run($"sc", $"start {serviceName}");

 

It works mostly, but sometimes it throws the following exception:

SmartBear.TestLeft.ApiException: The application 'sc' (PID 25376) exited with code 0 before the test engine could access it.

What would be the best way to work with Windows services?

I mostly need to start a service (and ideally wait for it to finish startup), stop it and also be able to check whether it is running.

 

Thank you!

  • Hi,

     

    I think that use of the Service Controller (like you do now) is a correct way to control applications of Windows Service type.

    I did not deal with them for some time and it is possible that something changed there, but:

    -- It was recommended to start/stop/pause service application via Service Controller;

    -- When Service Controller started service, it (controller) waited for some timeout (30 or 60 seconds IIRC) to get a notification from the service about the result of service initialization. If initialization took too long (e.g. because of slow access to some network resource), the Controller could report a problem but did not terminate the service. So the service had a chance to complete its initialization and the reported problem could be effectively ignored;

    -- As per the documentation (http://support.smartbear.com/docs/testleft/net-reference/html/M_SmartBear_TestLeft_ApplicationManager_Run.htm), the .Run() method returns a reference to the started process. You don't need this because you are not going to use sc process in your test code. (Actually, sc process should end as soon as the service is started.) So I think that instead of using .Run() method, you should use regular Windows API or .Net call that is intended to start some process (sc in your case), wait until the started process ends and, optionally, report the call result;

    -- You may use the .TryFind() method in your test code to check whether or not the process of your service exists in the system and act accordingly (start or stop the service as needed).

     

  • AlexKaras's avatar
    AlexKaras
    Champion Level 3

    Hi,

     

    I think that use of the Service Controller (like you do now) is a correct way to control applications of Windows Service type.

    I did not deal with them for some time and it is possible that something changed there, but:

    -- It was recommended to start/stop/pause service application via Service Controller;

    -- When Service Controller started service, it (controller) waited for some timeout (30 or 60 seconds IIRC) to get a notification from the service about the result of service initialization. If initialization took too long (e.g. because of slow access to some network resource), the Controller could report a problem but did not terminate the service. So the service had a chance to complete its initialization and the reported problem could be effectively ignored;

    -- As per the documentation (http://support.smartbear.com/docs/testleft/net-reference/html/M_SmartBear_TestLeft_ApplicationManager_Run.htm), the .Run() method returns a reference to the started process. You don't need this because you are not going to use sc process in your test code. (Actually, sc process should end as soon as the service is started.) So I think that instead of using .Run() method, you should use regular Windows API or .Net call that is intended to start some process (sc in your case), wait until the started process ends and, optionally, report the call result;

    -- You may use the .TryFind() method in your test code to check whether or not the process of your service exists in the system and act accordingly (start or stop the service as needed).