Catalin
Posts: 4206
Joined: Wed Jun 13, 2018 7:49 am

Start service with parameters received from .INI file

Fri Feb 07, 2020 12:22 pm

Hello guys,

REQUIREMENTS: At least the Professional suite and Advanced Installer 16.7 (if you want to build the attached solution. Otherwise, this is not a requirement anymore)

Recently, I've been asked if it is possible to pass arguments to a service that are received from a configuration file (e.g. an INI file).

The answer to this is yes, it is possible. However, we need to keep in mind that this scenario has two sub-scenarios, as it follows:

1. the .INI file is present on the target machine - this can be achieved through our predefined support for searches.

2. the .INI file is not present on the target machine and the file is intended to be delivered with the setup - unfortunately, for this, there is no predefined support and we will need to use a custom approach.

Let's recap this so we can better understand this scenario.

Let's consider we have the following .INI file:

Code: Select all

[SectionSample]
MyName = Catalin

[SectionSample2]
MyAge = 23
SOLUTIONS:

1. the .INI file is present on the target machine - this can be achieved through our predefined support for searches.

In this case, we would like to pass the value of "MyName" (which is "Catalin" - without quotes) as a parameter to our service.

To do so, we can create a search that will get the value from the .INI file. The search could look like this:
SearchSample.png
SearchSample.png (71.12 KiB) Viewed 9776 times

The biggest problem we face here is the fact that we need to know where the .INI file resides. In my case, I have placed the .INI file in the "C:\" volume, therefore I have used the [WindowsVolume] property, which resolves, at install time, to the volume where the OS is installed (in my case, C:\).

For more information about this, you can have a look over our "Paths of the folders in the "Files and Folders" Page" article.

After doing so, we can go to "Services" page and add our argument, as it follows:
ServiceArguments.png
ServiceArguments.png (82.35 KiB) Viewed 9776 times

After doing so, according to the log file, the service will be started with the required parameters:
InstallServices: Service:
MSI (s) (C4:C0) [11:52:13:639]: Executing op: ActionStart(Name=StartServices,Description=Starting services,Template=Service: [1])
Action 11:52:13: StartServices. Starting services
MSI (s) (C4:C0) [11:52:13:639]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (C4:C0) [11:52:13:639]: Executing op: ServiceControl(,Name=sample.exe,Action=1,Wait=1,StartupArguments=--someParameter=Catalin)
2. the .INI file is not present on the target machine and the file is intended to be delivered with the setup - unfortunately, for this, there is no predefined support and we will need to use a custom approach.


The problem that is encountered here is the fact that the searches are executed right when the setup starts, which means that your .INI file will not be available, therefore the search will be empty. This is why a custom approach is needed here.

If you go to "Custom Actions" page, you can see that the "Searches" action group is placed at the top of the installation sequence.

Unfortunately, there is not much that can be done about this. The only solution left is a custom solution. Basically, here, we can have a custom action (e.g. a script / .EXE / .DLL file) which will look for our .INI file, extract the data from it and then further set a property to the extracted value.

Here is how this can be achieved:

- please go to "Files and Folders" page and add your .INI file as a temporary file using the "Add Temporary Files" button from the toolbar.

Optional: Normally, temporary folders are deleted when the installation process ends. To avoid this, you can double click on your temporary file and check the "Do not remove the file when setup ends" option.

The script that will do the work for us is written in PowerShell (as I am not very familiar with other scripting/programming languages).

- now please go to "Custom Actions" page and add a "PowerShell" custom action, with sequence.

- uncheck the "Uninstall" and "Maintenance" options from under the "Dialogs Stage Condition" section (as we only want this executed during Install)

- the PowerShell custom action should be scheduled as it follows:

Wizard Dialogs Stage --> after "Paths Resolution" action group

- the PowerShell script could look as it follows:

Code: Select all

# Block for declaring the script parameters.
Param()

# Your code goes here.

# get the value of the TempFolder property and store it in a variable

$tempFolder = AI_GetMsiProperty TempFolder

# as the path to the .INI file is %temp%\NameOfTheIniFile.ini, we join the paths to create the full path to our INI file

$pathToIni = Join-Path -Path $tempFolder -ChildPath "sample.ini"

$sampleIni = Get-Content $pathToIni | Where-Object {$_ -match "="} | ConvertFrom-StringData

# set a property to our required INI value

AI_SetMsiProperty MY_PROP $sampleIni.MyName
Explanation for the following line (which I did not explain in the code because the explanation is a bit longer):

Code: Select all

$sampleIni = Get-Content $pathToIni | Where-Object {$_ -match "="} | ConvertFrom-StringData
Basically, here, we use the Get-Content PowerShell cmdlet, which gets the content of a file.

This scenario here indicates the fact that we can use the ConvertFrom-StringData cmdlet, which converts a string containing one or more key and value pairs to a hash table.

Unfortunately, this cmdlet only accepts the "key=value", meaning that, if our .INI file contains sections (e.g. "[Section]"), this cmdlet will fail, because [Section] does not respect the key=value format. To avoid such scenario, we have piped the content returned by our Get-Content cmdlet to only match objects that contain "=" (as in key=value).

Attached below, for your reference, is a .ZIP file containing the following files:

- the .AIP file

- a sample executable (sample.exe)

- a sample INI file (sample.ini)


which you can download and build on your machine.

Important: The "sample.exe" service can not be started with the parameters I've passed, so the service will never actually start. However, you can easily replace this .EXE with a .EXE file that accepts parameters and retest the scenario.

Hope this helps.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Sample Projects”