Install a service on Windows (Vista/XP/7) using Inno Setup

前端 未结 3 946
别那么骄傲
别那么骄傲 2021-02-02 04:45

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}\\my         


        
相关标签:
3条回答
  • 2021-02-02 04:58

    use Service Functions for Inno Setup from Silvio Iaccarino

    0 讨论(0)
  • 2021-02-02 05:00
    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.

    0 讨论(0)
  • 2021-02-02 05:16

    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.

    0 讨论(0)
提交回复
热议问题