5

I need to install and run a service when install an application (installer.exe is created using Inno Setup)

I used codes below

[Run]
Filename:"{sys}\myservice.exe "; Parameters: "-install"

I am not sure if this is correct

(I add codes to reminder reboot but I wonder if it is possible to run the service immediately after installation without reboot pc.)

[Setup]
AlwaysRestart=yes

Welcome any comment.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
monsabre
  • 2,099
  • 3
  • 29
  • 48
  • 1
    A service can be run immediately after it is installed, I do this all the time. Although a reboot could be required in your case if the installer has to replace files that are in use. – The_Fox Mar 24 '11 at 07:46
  • If I recall, the recommendation for installing services is not to use self-install of the service, but to write all the registry keys direct from the installer. – David Heffernan Mar 24 '11 at 07:55
  • AFAIK you should use SCM (service control manager) API to install a service, not access the registry. –  Mar 24 '11 at 08:48
  • @Idsandon Quite often service self-install will involve writing configuration to registry. That's the bit that should be done by the install program. Agreed that actually getting the service recognised by SCM should be done by SCM. Again that should be done by the installer and not by self-install as per OP's question. – David Heffernan Mar 24 '11 at 09:01
  • 2
    @David Heffernan: one thing is writing to HKLM\Software, another writing to HKLM\System. The SCM API is a well defined and published API. I understand that writing to the registry is easier than using the API, but the API IMHO is the **safest** way to handle service registration - I can't find anything you can't do using that API and that requires direct registry manipulation. –  Mar 24 '11 at 11:03
  • @Idsandon If the service has no configuration then yes you are right that SCM is all you need. But some services have config specific to the service. My original comment was exceedingly unclear. – David Heffernan Mar 24 '11 at 11:07
  • @David Heffernan: what configurations needs to be written to HKLM\System and can't be done using the SCM API? –  Mar 24 '11 at 11:41
  • @Idsandon Service specific settings. – David Heffernan Mar 24 '11 at 11:43
  • 1
    What are "service specific settings"? If they are not Windows services settings, but application-specific code settings, they should be written under HKLM\Software, not HKLM\System. Of course SCM can't deal with application-specific settings. Anyway, not all services needs to start with LocalSystem privileges (and shouldn't, if possibile), thereby the need of accessing the registry should be carefully assessed, and properly setup. –  Mar 24 '11 at 14:28
  • @user629453: I advice to remove the `AlwaysRestart=yes` [setup] directive, with the @ldsandon library you can check if the service is running (during upgrade) stop the service, install and then start the service again, so let the installer decide if a restart is needed as usual. – jachguate Mar 24 '11 at 17:00

3 Answers3

17
  1. Use sc.exe, It is simple, the only drawback is you may have to intercept and parse output to know what went wrong, if it did.
  2. Use my Inno Setup service library. It's a Pascal Script wrapper over the SCM API, and let you to control the services fully. A little more complex to use, but it allows for full error checking and handling. There are some higher level functions designed to display errors in standard suppressible Inno Setup dialog boxes.

PS: don't install your service in any of the Windows systems folder. They should be regarded as Windows private folders. Unless you have very, very good reasons to write there (i.e. drivers), you should never install software there. Install it in your application folders.

Sasikumar Murugesan
  • 4,412
  • 10
  • 51
  • 74
7

In addition to the accepted answer I'd just like to make it easier for people to use Luigi Sandon's service library (thank you very much!). After downloading the script you'll need to add a [Code] section similar to the following to your setup script:

[Code]
// source: https://stackoverflow.com/a/5416744 
#include "services_unicode.iss"

const
  SERVICE_NAME = 'MyService';
  SERVICE_DISPLAY_NAME = 'MyService';
  SERVICE_EXE = 'MyService.exe';

procedure CurStepChanged(CurStep: TSetupStep);
begin
  Log('CurStepChanged(' + IntToStr(Ord(CurStep)) + ') called');

  if CurStep = ssInstall then begin
    if ServiceExists(SERVICE_NAME) then begin
      if SimpleQueryService(SERVICE_NAME) = SERVICE_RUNNING then begin
        SimpleStopService(SERVICE_NAME, True, False);
      end;
      SimpleDeleteService(SERVICE_NAME);
    end;
  end
  else if CurStep = ssPostInstall then begin
    SimpleCreateService(SERVICE_NAME, SERVICE_DISPLAY_NAME, ExpandConstant('{app}\' + SERVICE_EXE), SERVICE_AUTO_START, '', '', False, False);
    SimpleStartService(SERVICE_NAME, True, False);
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  Log('CurUninstallStepChanged(' + IntToStr(Ord(CurUninstallStep)) + ') called');

  if CurUninstallStep = usUninstall then begin
    if ServiceExists(SERVICE_NAME) then begin
      if SimpleQueryService(SERVICE_NAME) = SERVICE_RUNNING then begin
        SimpleStopService(SERVICE_NAME, True, False);
      end;
      SimpleDeleteService(SERVICE_NAME);
    end;
  end;
end;

This isn't bulletproof but should handle the vast majority of cases just fine.

Unfortunately I couldn't figure out if there was a way to use the {# VarName} emit syntax in the [Code] section, which is why I declared the service name etc. as constants there as well as #define's at the top of the file. The answers here are useful if the constant you want is one of the [Setup] section's settings, but as you can't arbitrarily add things to that section this doesn't work for all things you might want to define constants for.

If you want to set a description for your service then the service library doesn't support that, but it's easy enough to do using the [Registry] section, for example:

[Registry]
; set the service description
Root: HKLM; Subkey: "System\CurrentControlSet\Services\{#ServiceName}"; ValueType: string; ValueName: "Description"; ValueData: "{#ServiceDescription}"; Flags: deletevalue uninsdeletekey

Lastly, I can confirm that this works on Windows 10 too.

maltem-za
  • 1,225
  • 2
  • 16
  • 23
1

use Service Functions for Inno Setup from Silvio Iaccarino

SimaWB
  • 9,246
  • 2
  • 41
  • 46
  • 1
    But be careful if you're using the Unicode version of Inno Setup - then these scripts won't work. See the answer from @ldsandon - and note the link at the bottom of his 'service library' page. – shunty Mar 24 '11 at 09:02