Search code examples
inno-setupinipascalscript

How to pass a ini script and a exe setup in inno script


procedure InstallNetTime(); Forward;   
procedure CreateNTPRegistryEntries(); Forward;        


procedure InstallNetTime();  
begin   

    if RegKeyExists(HKEY_LOCAL_MACHINE_32,'SOFTWARE\MICROSOFT\Windows\CurrentVersion\Uninstall\NetTime_is1') then  
    begin         
       exit;  
    end;

    ShowStatusMessage('Installing NetTime...');     
    CreateNTPRegistryEntries();   
    ExtractTemporaryFile('NetTime-2b7.exe');   
    RunProcess('{tmp}\NetTime-2b7.exe', '');    
 end;

procedure CreateNTPRegistryEntries();     
begin      
     RegDeleteKeyIncludingSubkeys ( HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective            Software\NetTime');  
     RegWriteStringValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'Hostname', '127.0.0.1');      
     RegWriteDWordValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'Protocol', 2);  
     RegWriteDWordValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'Port', 37);  
     RegWriteDWordValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'SyncFreq', 600);      
     RegWriteDWordValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'LostSync', 7500);  
     RegWriteDWordValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'WarnAdj', 120);  
     RegWriteDWordValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'Retry', 600);      
     RegWriteDWordValue(HKEY_LOCAL_MACHINE_32, 'SOFTWARE\Subjective
 Software\NetTime', 'Server', 1);   
 end;

I have to do a silent installation that's why I'm using inno scripts. I am using a ini file for the extra information and calling a RunProcess() method to pass this ini file as a parameter. First I am extracting the setup and ini file then calling the Runprocess() method, like below:

ExtractTemporaryFile('ntp-setup-win32.exe');
ExtractTemporaryFile('MeinBergNTP.ini');
RunProcess('msiexec', AddQuotes(ExpandConstant('{tmp}\ntp-setup-win32.exe')) 
  + AddQuotes(ExpandConstant('{tmp}\MeinBergNTP.ini'))
  + ' /quiet /norestart'); 

The second and third lines are executing as i can see the entries of setup into registry. But RunProcess() method is not working here. Installer just skips this step. I don't have much idea that how to pass the arguments and exe file together as i am new to Inno Scripts and not finding enough docs on it. Please help me out that how should I use the RunProcess() method. Or How can I silent install using the RunProcess() method.


Solution

  • A RunProcess() function doesn't exist in Inno Setup (by default), unless you create it yourself.

    You might solve the problem by using Exec.

    First argument is the file to execute. The second argument is the params to pass to it.

    var
      ResultCode: Integer;
    begin
      // Launch installer and wait for it to terminate
      if Exec(ExpandConstant('{tmp}\ntp-setup-win32.exe'),
              ExpandConstant('{tmp}\MeinBergNTP.ini') + ' /quiet /norestart',
              '', SW_SHOW,ewWaitUntilTerminated, ResultCode) then
      begin
        // handle success
      end 
      else begin
        // handle failure
      end;
    end;
    

    Thanks for the reply. But I need to use RunProcess() as all other iss files are using this method only. With exec() method its working fine though :).

    You could write a wrapper function.

    RunProcess()

    Build a wrapper function RunProcess() around Exec(), which accepts the Executable and its Parameters.

    function RunProcess(Executable: String, Parameters: String): Integer;
    var 
        ResultCode: Integer;
    begin
        Exec( ExpandConstant(Exectuable),
              ExpandConstant(Parameters),
             '', SW_SHOW,ewWaitUntilTerminated, ResultCode);
        Result := ResultCode;
    end;
    

    Usage:

    RunProcess('{tmp}\ntp-setup-win32.exe', '{tmp}\MeinBergNTP.ini /quiet /norestart');
    

    RunProcessHidden()

    Well, there are a lots of ways to hide the exec:

    • You could try switching the value for the ShowCmd parameter of the Exec() function to SW_HIDE.
    • Or you could invoke your executable through start /b .... Check start /? for its options.
    • Or you could also insert a little helper tool, like RunHiddenConsole.exe or HideExec.exe into your installer and then invoke your executable through that.

      1. Include the helper tools

        [Files]
        Source: RunHiddenConsole.exe; DestDir: {tmp}; Flags: dontcopy
        
      2. Extract

        // extract unzip util from the compressed setup to temp folder and define a shortcut
        ExtractTemporaryFile('RunHiddenConsole.exe');
        hideConsole := ExpandConstant('{tmp}\RunHiddenConsole.exe');
        
      3. Add wrapper function RunProcessHidden() to invoke the tool with Command parameter

        // Run an external command via RunHiddenConsole
        function RunProcessHidden(Command: String): Integer;
        var
            ErrorCode: Integer;
        begin
           if Exec(hideConsole, ExpandConstant(Command), '', SW_SHOW, ewWaitUntilTerminated, ErrorCode) then
           begin
               Result := ErrorCode;
           end
           else
           begin
              Log('[Error] ExecHidden failed executing the following command: [' + ExpandConstant(Command) + ']');
              Result := ErrorCode;
           end;
        end;