claudenoel
Posts: 17
Joined: Mon Oct 22, 2018 1:25 pm

Start a service only if it was running before the installation

I have a list of services that I need to check if they are running, stop them at the beginning of the installation, then restart them at the end of the installation only if they were running at the beginning. How can I handle this task?
Catalin
Posts: 6584
Joined: Wed Jun 13, 2018 7:49 am

Re: Start a service only if it was running before the installation

Hello,

This can be done through our predefined "Detect Service", "Stop Service" and "Start Service" custom actions. The "Detect Service" custom action will detect the desired service and will set the "AI_SERVICE_STATE" property to either "Started" or "Stopped". We will further use this property to either stop or start the services. For example, we will stop a service only if it was started. To do this, we can condition the "Stop Service" custom action as it follows:

Code: Select all

AI_STATE_PROPERTY = "Started"
The same goes with the "Start Service" custom action. We will start the service only if it is stopped.

Hope this helps.

Kind regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
claudenoel
Posts: 17
Joined: Mon Oct 22, 2018 1:25 pm

Re: Start a service only if it was running before the installation

Thanks. So, for several services, I need to copy the value AI_SERVICE_STATE in my own variables (properties) to be used later to start the service or not. Right?

Is there similar functions for scheduled tasks?
Catalin
Posts: 6584
Joined: Wed Jun 13, 2018 7:49 am

Re: Start a service only if it was running before the installation

Hello,

Yes, for more than one service, you can store the [AI_SERVICE_STATE] property in a public property and then further use it in a condition. To do so, after every "DetectService" custom action, you can add a "SetProperty" custom action configured as it follows:

Property: YOUR_PROP
Value: [AI_SERVICE_STATE]


In what regards the scenario related to scheduled tasks, I am afraid I do not understand it. Can you please give me some more details about what you want to achieve?

Kind regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
claudenoel
Posts: 17
Joined: Mon Oct 22, 2018 1:25 pm

Re: Start a service only if it was running before the installation

I need to verify if a scheduled task is running and if so, stop it, make it disabled in order to not interfere with the setup, then enable it at the end of the installtion.
Catalin
Posts: 6584
Joined: Wed Jun 13, 2018 7:49 am

Re: Start a service only if it was running before the installation

Hello,

I am afraid that we do not offer predefined support for this. However, you can achieve this through a custom action. For example, you can use our predefined support for "PowerShell Inline Script" custom action which will detect if your service state is "running" and if so, it will stop it and then disable it. Here is a small script which you can use to achieve what you want:

Code: Select all

$state = (Get-ScheduledTask | where TaskName -eq 'Scheduled Task Name').State
$state
if ($state -eq 'Running'){
Stop-ScheduledTask -TaskName 'Scheduled Task Name'
Disable-ScheduledTask -TaskName 'Scheduled Task Name'
}
Hope this helps.

Regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
claudenoel
Posts: 17
Joined: Mon Oct 22, 2018 1:25 pm

Re: Start a service only if it was running before the installation

Thanks Catalin.

I'm not familiar with powershell. Is it possible to store the $state value to be used at the end of the installation to re-enable the task via powershell?
Catalin
Posts: 6584
Joined: Wed Jun 13, 2018 7:49 am

Re: Start a service only if it was running before the installation

Hello,

There is to need to preserve the "$state" variable value for this. In this case, all you have to do is to create another custom action ("PowerShell script inline"), schedule it after the "Finish Execution" action group (simply drag and drop it after "Finish Execution" action group) and you can use the following script:

Code: Select all

$state = (Get-ScheduledTask | where TaskName -eq 'Your Schedule Task Name').State
if ($state -eq 'Disabled'){
Enable-ScheduledTask -TaskName 'Your Schedule Task Name'
}
We will again check for the state of a specific scheduled task and, if the state is "Disabled", we will simply enable it.

Hope this helps.

Kind regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
claudenoel
Posts: 17
Joined: Mon Oct 22, 2018 1:25 pm

Re: Start a service only if it was running before the installation

Finally, I created a C# custom action. The method I used is to call a DisableTask custom action on which I declare CustomActionData using the following form: TaskName=SDMsgUpdate (SD);TaskProp=TASK_PROP
I recover these values in my custom action and set the specified properties to the state value. And it works fine!

[CustomAction]
public static ActionResult DisableTask(Session session)
{
string taskName = session.CustomActionData["TaskName"];
string propName = session.CustomActionData["TaskProp"];
try
{
using (TS.TaskService ts = new TS.TaskService())
foreach (TS.Task task in ts.RootFolder.Tasks)
if (task.Name == taskName)
{
if (task.State == TS.TaskState.Running)
{
task.Stop();
}
session[propName] = task.State.ToString();
task.Enabled = false;
break;
}
return ActionResult.Success;
}
catch (Exception ex)
{
session[propName] = "Failure";
return ActionResult.Failure;
}
}

So, with this custom action, I can call it several times passing the name of the scheduled task and getting back its status directly in the property I want.

HOWEVER, since this is working fine for scheduled task, I decided to create a similar routine for the services (instead of using built-in action to stop the service and save the returned value to my property). But for an unknown reason, it stops the service but does not return the value in my property.

My custom action is called the same way as above (i.e. ServiceName=SSDPSRV;ServiceProp=SVC_PROP) but SVC_PROP does not get the status. Here is my C# code (I tried setting it with ServiceControllerStatus.Running.ToString() or by assigning a string like shown below):

[CustomAction]
public static ActionResult StopService(Session session)
{
string serviceName = session.CustomActionData["ServiceName"];
string propName = session.CustomActionData["ServiceProp"];
ServiceController service = new ServiceController(serviceName);
try
{
if (service.Status == ServiceControllerStatus.Running)
{
session.CustomActionData[propName] = "Running";
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMilliseconds(30000));
}
else
{
session.CustomActionData[propName] = "Stopped";
}
return ActionResult.Success;
}
catch (Exception ex)
{
session[propName] = "Failure";
return ActionResult.Failure;
}
}

Any idea why?
Catalin
Posts: 6584
Joined: Wed Jun 13, 2018 7:49 am

Re: Start a service only if it was running before the installation

Hello Claude,

First of all, "CustomActionData" property is a special property. Installer Properties are available only during the immediate stage of the install execution process. After this stage is complete all property values are set to empty strings. The exception to this rule is the special "CustomActionData" property which keeps its values through all of the stages even during deferred, rollback and commit.

Since you are using it, I am assuming that your custom action is set to run as "deferred". If that is the case, please keep in mind that you can not set properties during the "deferred" execution time. During the "deferred" execution time, you can only get properties values.

Hope this helps.

All the best,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
claudenoel
Posts: 17
Joined: Mon Oct 22, 2018 1:25 pm

Re: Start a service only if it was running before the installation

Well, not sure to understand. Both of my actions, DisableTask and StopService are identical (i.e. both action should set a passed property to the value I want) and used one after the other at the same stage. I get a property for all the Scheduled Tasks that I want the status then all the services that I want to monitor the status. All of these CA are called one after the other. As I said, I am able to store the scheduled task state in the appropriate custom property, but those from the service are not working. As you can see in my previous email, the custom actions are identical. I am wondering why the custom property is not set for the service when they are from the scheduled task. It is really weird to me. I might be missing something...
Catalin
Posts: 6584
Joined: Wed Jun 13, 2018 7:49 am

Re: Start a service only if it was running before the installation

Hello Claude,

To be honest, I am not sure why that happens. Could you please attach some screenshots of how you have configured your custom actions?

Also, you can try to debug your custom action by making use of the following article:

https://www.advancedinstaller.com/user- ... et-ca.html

Hope this helps.

Kind regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
claudenoel
Posts: 17
Joined: Mon Oct 22, 2018 1:25 pm

Re: Start a service only if it was running before the installation

Thanks for the debug procedure. It helped me a lot and I found what was wrong. Everything's perfect now!
Catalin
Posts: 6584
Joined: Wed Jun 13, 2018 7:49 am

Re: Start a service only if it was running before the installation

You are always welcome, Claude.

I am glad you got this working.

All the best,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Common Problems”