Run application after click on the Finish button (not after install) - inno-setup

I have a setup for installing my application, and I need to run the application after successfully installing. I used postinstall to do this.
but it shows a checkbox and the user can uncheck it. I need to run the application without asking because of it kinda service which needs to runs at startup. if the user unchecked it he needs to restart the PC to launch.
So I can use the Filename: "{app}\myapp.exe" code without any flags in the Run section to launch the application but the problem is, It runs immediately after installing not after the finish button clicked.
The first issue is my application has an instruction window. it shows up at the launch so the setup window goes to the back. And the second issue is my application does not allow terminating unless uninstall becouse it need to run in the background. Setup waiting to process end to finish.
Is there any way to run the application after the finish button click in inno setup?

Simplifying the answer from Run Files and Programs according to custom checkboxes after clicking on Finish Button in Inno Setup, you can use a code like this:
[Code]
function NextButtonClick(CurPageID: Integer): Boolean;
var
ResultCode: Integer;
Path, Msg: string;
begin
if CurPageID = wpFinished then
begin
Path := ExpandConstant('{app}\MyProg.exe');
if ExecAsOriginalUser(Path, '', '', SW_SHOW, ewNoWait, ResultCode) then
begin
Log('Executed MyProg');
end
else
begin
Msg := 'Error executing MyProg - ' + SysErrorMessage(ResultCode);
MsgBox(Msg, mbError, MB_OK);
end;
end;
Result := True;
end;
Replace ExecAsOriginalUser with Exec, if you want to run the program with elevated/Administrator privileges (if the installer uses them at all).

Add code section to your script like this:
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
ResultCode: Integer;
begin
if CurStep = ssDone then
Exec(ExpandConstant('{app}\MyProg.exe'), '', '', SW_SHOW, ewNoWait, ResultCode);
end;
It will be triggered only on a success installation.
Use ExecAsOriginalUser instead of Exec if you don't want the exe run as admin.

Related

Inno Script: Skip password if the application is already installed

I am trying to create an Inno Setup installer that will require a password from the user if the application has never been installed on the local machine.
I have the script that gets a password, and I have a Code section that checks for the existence of the uninstall registry key, but being new to Inno Setup scripting, I'm not sure how to link the two parts together.
Can anyone explain how to forgo the user from entering a password if the app is already installed?
Here is the (test) script...
#define myAppID "2B7D6E48-74A8-4070-8BA7-621115D6FD00"
[Setup]
AppId={{{#myAppID}}
Password=123456
[Code]
function checkForPreviousInstall(): Boolean;
begin
Result := False;
if RegKeyExists(HKEY_LOCAL_MACHINE,'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#myAppId}_is1') or
RegKeyExists(HKEY_CURRENT_USER, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#myAppId}_is1') then
begin
MsgBox('The application is installed already.', mbInformation, MB_OK);
Result := True;
end;
end;
Skip the password page, if the application is installed already.
Use ShouldSkipPage event function:
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if (PageID = wpPassword) and checkForPreviousInstall then Result := True;
end;

How to use Inno Setup to run a command like steam://

I am trying to make my Inno Setup program to run this command steam://
This command is used to open Steam program via the windows RUN tool.
I press WindowsKey+R and type the command steam:// and it opens the Steam program.
How can i make Inno Setup call this command?
I tried the following without success:
[Run]
Filename: "C:\Users\LUCAS\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Accessories\Run.lnk"; Parameters: "steam://;
also tried that code bellow, and calling AfterInstall: RunOtherInstaller; on [Files] section, but it gives error on installation: %1 is not a valid Win32 application
[Code]
procedure RunOtherInstaller;
var
ResultCode: Integer;
begin
if not Exec(ExpandConstant('C:\Users\LUCAS\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Accessories\Run.lnk'), 'steam://', '', SW_SHOWNORMAL,
ewWaitUntilTerminated, ResultCode)
then
MsgBox('Error!!' + #13#10 +
SysErrorMessage(ResultCode), mbError, MB_OK);
end;
This link is a little strange... It actually points to nowhere when i try to follow it, but it is what calls the windows RUN tool.
I know i could call the Steam.exe from the default folder C:\Program Files (x86)\Steam\Steam.exe but i am trying to avoid problems with users who not have Steam on default folder... So i am trying to use this method running this "External Protocol" (i dont know if this is the right name for it): steam://
You can check registry for Steam location.
Part of my script for triggering installation:
[Code]
function SteamNotInstalled(): Boolean;
var
Path: String;
ErrorCode: Integer;
begin
Result := True;
if (RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\Valve\Steam',
'InstallPath', Path)) and (FileExists(Path + '\Steam.exe')) then begin
ShellExec('', ExpandConstant('"' + Path + '\Steam.exe' + '"'), ' -install' + ExpandConstant(' "{src}"'),
'', SW_SHOW, ewNoWait, ErrorCode);
Result := False;
end;
end;
Or you can use shellexec in [Run] section
You can open the steam:// URL as any other URL.
procedure OpenUrl(Url: string);
var
ErrorCode: Integer;
begin
ShellExec('open', Url, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;
Or use postinstall [Run] section entry:
[Run]
Filename: steam://xxx; Description: "Run game"; Flags: postinstall shellexec
See also
How to open a web site after uninstallation?
Inno Setup Compiler: How to auto start the default browser with given url?

Execute different BLOCK of commands in Inno Setup Run section based on Windows version

I know there is already question Execute different command in Inno Setup Run section based on Windows version with very good answer.
My question is how to perform different blocks of commands for different target Windows versions. My problem is that I have ~10-15 commands that need to perform if target version is Windows 7 and the ~same amount of different commands for Windows 8 or above.
Is it possible to avoid the need to add ; OnlyBelowVersion: 6.2 after each command needed for first case and ; MinVersion: 6.2 after each command in the second block?
I know there is preprocessor conditions "#if", #else and #endif but that of course works only at compilation time
The question and answers Determine Windows version in Inno Setup although may look similar to this question are NOT answering it. I know how to determine Windows version in Inno Setup. I also know about those ; MinVersion: 6.2 and ; OnlyBelowVersion: 6.2 options. I am asking if it is possible to specify a block of commands (10-15 commands) and apply that option to entire block, not to each and every command individually.
The goal is not to avoid "cryptic version numbers" but to avoid repeating the same condition many times. And to avoid risk of forgetting it when block will grow over the time.
The solution that I found so far is to use CurStepChanged procedure:
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
if IsWindows8OrLater() then
MsgBox('Running on Windows 8 Or Later', mbInformation, MB_OK)
{ 15 comands or call of W8-specific procedure goes here }
else begin
MsgBox('Running on Windows 7', mbInformation, MB_OK);
{ 15 comands or call of W7-specific procedure goes here }
end;
end;
But it looks a bit ugly to me...
There are no block-control features in the .iss file.
All you can do, to avoid repeating the cryptic version numbers, is to define a preprocessor variable like:
#define Windows8AndNewer "MinVersion: 6.2"
#define Windows7AndOlder "OnlyBelowVersion: 6.2"
[Run]
Filename: "Windows8-Command1.exe"; {#Windows8AndNewer}
Filename: "Windows8-Command2.exe"; {#Windows8AndNewer}
Filename: "Windows7-Command1.exe"; {#Windows7AndOlder}
Filename: "Windows7-Command2.exe"; {#Windows7AndOlder}
The only other way is to reimplement the [Run] section in the [Code] using the Exec function:
procedure Run(FileName: string);
var
ResultCode: Integer;
begin
Exec(FileName, '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
{ some error checking }
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
if GetWindowsVersion() >= $06020000 then
begin
Log('Running on Windows 8 or later');
Run('Windows8-Command1.exe');
Run('Windows8-Command2.exe');
end
else
begin
Log('Running on Windows 7 or older');
Run('Windows7-Command1.exe');
Run('Windows7-Command2.exe');
end;
end;
end;

Inno Setup Script - running exe before installing

I wanna run an application before installing and I'm using this code on Inno Setup Script(Pascal):
function InitializeSetup():boolean;
var
ResultCode: integer;
begin
// Launch Notepad and wait for it to terminate
if ExecAsOriginalUser('{src}\MyFolder\Injector.exe', '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
begin
// handle success if necessary; ResultCode contains the exit code
end
else begin
// handle failure if necessary; ResultCode contains the error code
end;
// Proceed Setup
Result := True;
end;
When I'm using "{win}\notepad.exe", It works but when I use "{src}\MyFolder\Injector.exe", Setup doesn't open my program and continues install.
Note : Injector has app.manifest which has 'requireAdministrator'. However this application should be run as administrator.
So what's wrong?
You need to use the ExpandConstant function when using values such as {src} in code.
However, InitializeSetup is also too early to run installation tasks. You should move this code into CurStepChanged(ssInstall).
Also, if it requires admin permissions it must be run with Exec, not ExecAsOriginalUser.
This May work for you... I believe that this problem is because of spaces in the entire path..that should overcome with double quoting the path...
Exec('cmd.exe','/c "'+ExpandConstant('{src}\MyFolder\Injector.exe')+'"', '',SW_SHOW,ewWaitUntilTerminated, ResultCode);
cheers..

Possibility to synchronize a setup with Inno Setup and read out return code

is it possible to start a Inno Setup, that waits until the child process has finished? The current systems default behaviour is that the setup starts the "real" setup in temporary folder and goes further in command line. My aim is that the parent process should wait until the child finishes to read out the return code in errorlevel variable. I've made a picture for better understanding
My 2nd question is how Inno handles the setup exit codes. Where can they read out after setup has finished? If an error occurs in setup or user clicks cancel the env-variable %errorlevel% is always 0.
Thanks in advance
What you are trying to do is a function of the OS, not really InnoSetup. Use the following to do what you want from a command prompt or batch file:
start /wait setup.exe
echo %ERRORLEVEL%
The following code sample calls child.exe during the post-install step:
procedure CurStepChanged(CurStep: TSetupStep);
var
ErrorCode: integer;
begin
if (CurStep = ssPostInstall) then
begin
WizardForm.Hide;
ShellExec('open', 'child.exe', '', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode);
WizardForm.Show;
if (ErrorCode <> 0) then
begin
// error handling
end;
end;
end;

Resources