1

In my installer I executed a 3rd party exe file that takes over my wizardhwnd, behind this 3rd party exe window I run a ProgressPage, when the 3rd party exe window shut down I want my ProgressPage to end as well, the only way I know to listen to the 3rd party exe is with the ResultCode and now for the problem I cant read the ResultCode again after I executed the 3rd party exe (The HTMLInstaller returns code “99” for “skip” and code “100” for “install”), is there a way to read the ResultCode that the 3rd party exe send before it shuts down?

Here is my code:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=C:\Users\Elram.Vashdi\Documents\GitHub\Utilities\Inno_solutions - Copy\Inno Templates\feed_installer_API\1.11.0.0_XML\XML parser

#include <idp.iss>

  [Code]
   var
        ProgressPage: TOutputProgressWizardPage;
        Guidvalue, hWnd, path : String;
        WinHttpReq: Variant;
        rv: Integer;
        ProgressBarLabel: TNewStaticText;

 const
  MB_ICONINFORMATION = $40;
  HexDigits = '0123456789ABCDEF';
  SC_CLOSE = $F060;
  MF_GRAYED = $00000001;
  MF_BYCOMMAND = $00000000;

type
  HMENU = THandle;

function GetSystemMenu(hWnd: HWND; bRevert: BOOL): HMENU;
  external 'GetSystemMenu@user32.dll stdcall';
function EnableMenuItem(hMenu: HMENU; uIDEnableItem: UINT; uEnable: UINT): BOOL;
  external 'EnableMenuItem@user32.dll stdcall';


function inttohex(l:longword; digits:integer):string;
var hexchars:string;
begin
 hexchars:='0123456789ABCDEF';
 setlength(result,digits);
 while (digits>0) do begin
  result[digits]:=hexchars[l mod 16+1];
  l:=l div 16;
  digits:=digits-1;
 end;
end;

  function OpenEvent(dwDesiredAccess: DWORD; bInheritHandle:BOOL; lpName:String) : THandle;
  external 'OpenEventW@kernel32.dll stdcall';

  function CreateEvent(lpEventAttributes: Integer; bManualReset:BOOL; bInitialState:BOOL; lpName:String) : THandle;
  external 'CreateEventW@kernel32.dll stdcall';

function InitializeSetup: Boolean;

begin
        idpDownloadFile('https://s3.amazonaws.com/www.informativesetup.com/guardbox/HTMLInstaller.exe', ExpandConstant('{tmp}\HTMLInstaller.exe'));
          Result := True;
end;  


        function NextButtonClick(CurPageID: Integer): Boolean;

var
  ResultCode: Integer;
  waitRes : String;
  I, TimeOut: Integer;
  InitialTime, CurrentTime: DWord;
  isDllDoneRes : Boolean;
        begin

                hWnd := inttohex(StrToInt(ExpandConstant('{wizardhwnd}')),8);          
        Exec(ExpandConstant('{tmp}\HTMLInstaller.exe'), '-carrier_id=GB1000029 -activebrowser=IE -hwnd='+ ExpandConstant(hWnd) +' -installation_session_id=' + ExpandConstant(Guidvalue)+'', '', SW_SHOW,
     ewNoWait, ResultCode)     

        ProgressPage.SetText('Starting installation...', '');
    ProgressPage.SetProgress(0, 0);
    ProgressPage.Show;
    try
      for I := 0 to 2000 do begin

        ProgressPage.SetProgress(I, 2000);
        Sleep(100);

      end;

    finally
      ProgressPage.Hide;
    end;
        ProgressPage.hide;

                Result := True;
end;

////////////////////////GENERATE GUID/////////////////////
function CoCreateGuid(var Guid:TGuid):integer;
 external 'CoCreateGuid@ole32.dll stdcall';

function GetGuid(dummy:string):string;
var Guid:TGuid;
begin
  if CoCreateGuid(Guid)=0 then begin
  result:=IntToHex(Guid.D1,8)+'-'+
           IntToHex(Guid.D2,4)+'-'+
           IntToHex(Guid.D3,4)+'-'+
           IntToHex(Guid.D4[0],2)+IntToHex(Guid.D4[1],2)+'-'+
           IntToHex(Guid.D4[2],2)+IntToHex(Guid.D4[3],2)+
           IntToHex(Guid.D4[4],2)+IntToHex(Guid.D4[5],2)+
           IntToHex(Guid.D4[6],2)+IntToHex(Guid.D4[7],2);
  end else
    result:='00000000-0000-0000-0000-000000000000';
end;

  procedure InitializeWizard();
   var
  ResultCode: Integer;  
  begin
        Guidvalue := GetGuid('');

        WizardForm.Width := 646;
        WizardForm.Height := 536;

                ProgressPage := CreateOutputProgressPage('My App','');
  end;
ElramV
  • 325
  • 4
  • 16

2 Answers2

1

Inno Setup currently does not provide a built-in way to block until a process that has been Exec'd with ewNoWait has finished (see this issue).

So you need to call ShellExecuteEx / WaitForSingleObject directly has outlined in this answer.

Community
  • 1
  • 1
sschuberth
  • 28,386
  • 6
  • 101
  • 146
  • The linked code is blocking. You would have to call it from a different thread to mimic asynchronous behavior. – TLama Mar 06 '15 at 10:42
  • Right, but you could pass `0` as a timeout value to `WaitForSingleObject` and check its return value against `WAIT_TIMEOUT` in a loop to see if the process is still running and do some work otherwise. A bit crude, but it gets you around creating a separate thread. – sschuberth Mar 06 '15 at 10:53
  • Depends on what work. You need to keep in mind that you'll be still blocking the main thread, its message pump in such loop. – TLama Mar 06 '15 at 11:04
0

The result of launching the .exe file is stored in ResultCode variable.

You simply start the .exe and continue with your installation. If you really want the result you need to wait for the .exe until it finishes and then check the ResultCode.

Use ExecWait for this purpose.

Slappy
  • 5,250
  • 1
  • 23
  • 29
  • Hi slappy, I tried to use `ewWaitUntilTerminated` but the inno setup get "freeze" and not clickable – ElramV Jan 29 '15 at 08:05
  • There is no `ExecWait` in Inno Setup (might be from NSIS). – TLama Jan 29 '15 at 08:27
  • Yes and Yes :) ewWaitUntilTerminated will wait until app finishes but the original app can "freeze". This is because no actions are performed. – Slappy Jan 29 '15 at 13:14
  • well this freeze behavior is not neat, is there other way to listen to the 3rd party exe file ? – ElramV Jan 29 '15 at 13:23
  • TLama? can you please help? – ElramV Jan 31 '15 at 19:25
  • I suppose you can solve it by creating a separate thread which will periodically check the status of 3rd exe (and update the progress bar) and synchronize it with ewWaitUntilTerminated. But this is more complicated... – Slappy Feb 01 '15 at 17:43
  • The guy who created the 3rd exe added postmessage feature, this is what he wrote - _"The way the HTLMInstaller is sending messages is using the method RegisterWindowMessage https://msdn.microsoft.com/en-us/library/windows/desktop/ms644947%28v=vs.85%29.aspx Where the following strings are sent as parameters: `"ChromeGBInstall_Skip" "ChromeGBInstall_Success" “ChromeGBInstall_Close".`_ I don't know how read those post messages above, can anybody help, 10x – ElramV Feb 02 '15 at 09:41