BeGiN
BeGiN

Reputation: 363

Run a batch file only one time when the installer starts

I'm having an issue here with the following:

function InitializeSetup(): Boolean;
var
  ResultCode:Integer;
begin
  Result := true;
  if MsgBox('Wanna help?',mbConfirmation, MB_YESNO )= IDYES then
  begin
    CreateBatch();
    Exec('cmd.exe', '/c "' +ExpandConstant('{tmp}\batch.bat'),'',SW_HIDE, ewWaitUntilTerminated, ResultCode);
    Result:= false;
  end;  
end;

in the batch file i got the following :

@ECHO OFF 
D:
cd D:\_INSTALLER\Output
"installer.exe" /SAVEINF="opt.txt"

So it basically re-open the installer , over and over again ... ( infinite loop )

Is there any way to ask : Wanna help? only for the 1st time ? and if the user clicked yes, the batch should be executed , else if the user clicked no it should continue the install normally.

Thanks in advance for the support , BeGiN.

Upvotes: 1

Views: 1564

Answers (2)

BeGiN
BeGiN

Reputation: 363

With the help of TLama and his post i achieved my goal by using the following script:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif

type
  HINSTANCE = THandle;
procedure ExitProcess(exitCode:integer);external '[email protected] stdcall';
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;lpParameters: string; lpDirectory: string; nShowCmd: Integer): HINSTANCE;
  external 'ShellExecute{#AW}@shell32.dll stdcall';

var
  withINF: Boolean;

function CmdLineParamExists(const Value: string): Boolean;
var
  I: Integer;
begin
  Result := False;
  for I := 1 to ParamCount do
    if CompareText(ParamStr(I), Value) = 0 then
    begin
      Result := True;
      Break;
    end;
end;

//Initialize setup
function InitializeSetup(): Boolean;
var
  ResultCode:Integer;
  Params: string;
  RetVal: HINSTANCE;
begin
  Result := true;
  withINF := CmdLineParamExists('/SAVEINF=opt.txt');
  if not withINF then
  begin
    Params := '/SAVEINF=opt.txt';
    ShellExecute(0, 'open',ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
    ExitProcess(0);
  end;
end;

L.E: A shorter code for doing the same thing also made by TLama(multilingual support added):

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
ShowLanguageDialog = yes

[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"

[Code]
#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif

type
  HINSTANCE = THandle;
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;lpParameters: string; lpDirectory: string; nShowCmd: Integer): HINSTANCE;
  external 'ShellExecute{#AW}@shell32.dll stdcall';


function CmdLineParamExists(const Value: string): Boolean;
var
  I: Integer;
begin
  Result := False;
  for I := 1 to ParamCount do
    if CompareText(ParamStr(I), Value) = 0 then
    begin
      Result := True;
      Break;
    end;
end;


function InitializeSetup: Boolean;
var
  Params: string;
begin
  // prepare Params variable for reusing
  if ExpandConstant('{language}') = 'en' then begin
    Params := '/SAVEINF=opt.txt /LANG=en';
  end;
  if ExpandConstant('{language}') = 'nl' then begin
    Params := '/SAVEINF=opt.txt /LANG=nl';
  end;
  // allow this setup to run if the expected parameter is specified; or, if it is not, allow to run it
  // when ShellExecute fails; it works like this - first evaluates the CmdLineParamExists function and
  // if that returns True, the second part of the statement (ShellExecute) won't run (evaluate); when
  // the parameter is not found, the CmdLineParamExists returns False and statement evaluation goes on,
  // ShellExecute attempts to run the setup and to the Result returns True (allow this instance to run)
  // when the function fails for some reason (the returned value <= 32); in other words, you will allow
  // this setup instance to run if executing of the new setup instance fails
  Result := CmdLineParamExists('/SAVEINF=opt.txt') or (ShellExecute(0, '', ExpandConstant('{srcexe}'), Params, '', SW_SHOW) <= 32);
end;

Regards, BeGiN

Upvotes: 1

Slappy
Slappy

Reputation: 5472

I see not reason for this but you can simply solve this by creating temp file.

If user clicks Yes (first time) then create some file (any file with some random content) just before CreateBatch() is called.

Then simply check for existence of this file - if it exists user already clicked Yes (once) and do what ever you want.

Upvotes: 0

Related Questions