Inno Setup Procedure not executing after install - installation

I have compiled multiple programs in inno setup i.e
Sql Server
.Net framework 3.5
Crystal Reports
Sql Script
the problem i am facing is that the procedure in which the code of executing the script is present does not execute after the installation of a program before it. If the program before it is cancelled then it execute.
[Files]
Source: "E:\Inno Data\Inno_Setup\Prerequisites\dotnetfx35\NDP451-KB2858728-x86-x64-AllOS-ENU.exe"; DestDir: {tmp}; AfterInstall: InstallFramework
Source: "E:\Inno_Setup\Prerequisites\CrystalReports105\CRRuntime_64bit_13_0_5.msi"; DestDir: {tmp}; AfterInstall: InstallCrystalReports
Source: "E:\Prerequisites\SQLServer2008R2SP2\SQLEXPRWT_x64_ENU.exe"; DestDir: {tmp}
;SQL Script Files
Source: "E:\SQLInstallTEST\Scripts\RCabSoft.sql"; DestDir:"{app}\Scripts"
[Run]
Filename: "{tmp}\SQLEXPRWT_x64_ENU.exe"; Parameters: "/ACTION=Install /INSTANCENAME=MSSQLSERVER /QS /HIDECONSOLE /INDICATEPROGRESS=""False"" /IAcceptSQLServerLicenseTerms /SQLSVCACCOUNT=""NT AUTHORITY\SYSTEM"" /SQLSYSADMINACCOUNTS=""builtin\users"" /SKIPRULES=""RebootRequiredCheck"" "; Check: isWin64();
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\CRRuntime_64bit_13_0_5.msi"" /qb"; WorkingDir: {tmp};
Filename: "{tmp}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe"; parameters: "/SILENT /NOCANCEL"; AfterInstall: sqlscript;
[Code]
procedure sqlscript;
var
ResultCode: Integer;
OutputText: String;
begin
if FileExists(ExpandConstant('{pf32}\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\SSMS.exe')) then
begin
ExtractTemporaryFile('RCabSoft.sql');
// Execute SQL Update Scripts
Exec('SqlCmd.exe', ' -e -E -S .' + ExpandConstant(' -i "{tmp}\RCabSoft.sql"'), '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
end;

Related

using Desktop App Converter sticks at "Waiting for installer process to complete inside Isolated Environment"

I am trying to convert an Install .exe file I made with inno-setup to an appx file using the Desktop App Converter from Microsoft. It hangs every time at "Waiting for installer to process to complete inside Isolated Environment".
The command that I am using in Desktop App Converter is:
DesktopAppConverter.exe -Installer "C:\Users\Desktop\Output\setup.exe" -Destination "C:\Users\Desktop\MyProgram\" -PackageName "MyProgramApps" -Publisher "Me"
-Version 0.1.4.0 -MakeAppx -Verbose -InstallerArguments "/VERYSILENT" -PackagePublisherDisplayName "MyApps" -PackageDisplayName "MyProgram" -AppDisplayName "MyProgram" -AppId "MyProgram"
When I run "MyProgram.exe from the command line using "/VERYSILENT" it installs completely silently.
The script from Inno-Setup is:
#define MyAppName "MyProgram"
#define MyAppVersion "0.1.7"
#define MyAppPublisher "MyApps"
#define MyAppExeName "MyProgram.exe"
[Setup]
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir=C:\Users\Desktop\Output
OutputBaseFilename=thirteenth_setup
Compression=lzma
SolidCompression=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "C:\Users\Desktop\resources\MyProgram.exe"; DestDir: "{app}"; Flags: ignoreversion
#define JavaInstaller "jre-8u151-windows-x64.exe"
Source: "{#JavaInstaller}"; DestDir: "{tmp}"; Flags: dontcopy
[Icons]
Name: "{commonprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; \
Description: "{cm:LaunchProgram,{#StringChange(MyAppName,'&', '&&' )}}"; \
Flags: nowait postinstall skipifsilent
[Code]
const
REQUIRED_JAVA_VERSION = '1.7';
function isJavaInstalled(): Boolean;
var
JavaVer : String;
tmpFileName,
pathJavaExe: String;
isGoodJavaVersion,
isFoundJavaPath: Boolean;
ResultCode: Integer;
ExecStdout: AnsiString;
begin
{ *** check in registry }
{ sets variables: }
{ JavaVer }
{ isGoodJavaVersion }
if RegQueryStringValue(HKLM, 'SOFTWARE\JavaSoft\Java Runtime Environment',
'CurrentVersion', JavaVer) AND (JavaVer <> '') OR
RegQueryStringValue(HKLM64, 'SOFTWARE\JavaSoft\Java Runtime Environment',
'CurrentVersion', JavaVer) AND (JavaVer <> '') then begin
Log('* Java Entry in Registry present. Version: ' + JavaVer);
isGoodJavaVersion := CompareStr(JavaVer, REQUIRED_JAVA_VERSION) >= 0;
end;
{ add additional checks, for example by searching the PATH, }
{ or by running `java -version` }
Result := isGoodJavaVersion;
end;
procedure ExtractInstaller;
begin
ExtractTemporaryFile('{#JavaInstaller}');
end;
[Run]
Filename: "{tmp}\{#JavaInstaller}"; Parameters: "SPONSORS=0"; \
StatusMsg: "Java Runtime Enviroment not installed on your system. Installing..."; \
Check: not isJavaInstalled; BeforeInstall: ExtractInstaller;
I think it has something to do with:
[Run]
Filename: "{tmp}\{#JavaInstaller}"; Parameters: "SPONSORS=0"; \
StatusMsg: "Java Runtime Enviroment not installed on your system. Installing..."; \
Check: not isJavaInstalled; BeforeInstall: ExtractInstaller;
because when I run it without that 'run' statement then DAC runs to a finish. But of course then the Java installer does not run.
You can also convert the packages with the new free Express edition from Advanced Installer, developed in partnership with Microsoft, its purpose is to complement the Desktop App Converter.
For example, the installation of your INNO package can be interactive, with UI, so you can manually run the installer and complete the installation, thus should be able to avoid the above problem.
It has a GUI that allows for advanced customization of the APPX packages, without requiring you to have knowledge about the internals package schemas.
If you have any questions about it, let me know, would love to help.
Disclaimer: I work on the team that builds Advanced Installer.

Installing Microsoft Access Database Engine prerequisite without user intervention in Inno Setup

I am continuing with my work in Inno Setup, So now I have a new questions about it.
I am trying of to execute some programs before install my final application, for this purpose I am using Exec function.
When I try with the following code:
[Files]
Source: "AccessDatabaseEngine_x64.exe"; DestDir: "{tmp}"; Flags: dontcopy noencryption
Source: "Database.accdb"; DestDir: "{app}"; Flags: ignoreversion
[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
Var
ResultCode: Integer;
begin
ExtractTemporaryFile('AccessDatabaseEngine_x64.exe');
if Exec(ExpandConstant('{tmp}\AccessDatabaseEngine_x64.exe'), 'quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
msgbox('True: {tmp}\AccessDatabaseEngine_x64.exe : ' + IntToStr(ResultCode), mbInformation, MB_OK);
end
else begin
msgbox('False: {tmp}\AccessDatabaseEngine_x64.exe : ' + SysErrorMessage(ResultCode), mbInformation, MB_OK);
end;
end;
I get this error:
On the other hand, if I use the follow code:
[Files]
Source: "AccessDatabaseEngine_x64.exe"; DestDir: "{tmp}"; Flags: dontcopy noencryption
Source: "Database.accdb"; DestDir: "{app}"; Flags: ignoreversion
[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
Var
ResultCode: Integer;
begin
ExtractTemporaryFile('AccessDatabaseEngine_x64.exe');
if Exec(ExpandConstant('{tmp}\AccessDatabaseEngine_x64.exe'), '', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
msgbox('True: {tmp}\AccessDatabaseEngine_x64.exe : ' + IntToStr(ResultCode), mbInformation, MB_OK);
end
else begin
msgbox('False: {tmp}\AccessDatabaseEngine_x64.exe : ' + SysErrorMessage(ResultCode), mbInformation, MB_OK);
end;
end;
I get the installation wizard of the another file. Some like this:
I want to install my other programs automatically, without user intervention.
Is it possible? Can you help me?
Thank for advance!
The usage screen says /quiet, and you use quit.
So use /quiet, not quit:
if Exec(ExpandConstant('{tmp}\AccessDatabaseEngine_x64.exe'), '/quiet', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
I was inattentive, the correct answer is in the first picture. The word that should be used is: /quiet; not /quite, not /quit.
As support (if this happens again to someone other) I leave the next link:
Description of the command-line switches that are supported by a software installation package, an update package, or a hotfix package that was created by using Microsoft Self-Extractor
.
Likewise many thaks for you attention.
The option needed is :
/passive Runs the update without any interaction from the user.
if Exec(ExpandConstant('{tmp}\AccessDatabaseEngine_x64.exe'), '/passive', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then

Download a file while installing by inno setup

[Files]
Source: D:\VBproject\YY\inst\YY.exe; DestDir: {app}; Flags: ignoreversion
Source: D:\VBproject\YY\inst\YY.dll; DestDir: {app}; Flags: ignoreversion
That is my file list above, and I want to install the YY.dll from the internet for example
http://www.example.com/yy.dll , not pack it to setup.exe
Is there any way can do that? Thanks alot
I have used the ISTool plugin:
#include 'C:\Program Files (x86)\ISTool\isxdl.iss'
[Code]
const
dotnetRedistURL = 'http://www.example.com/yy.dll ';
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
isxdl_AddFile(dotnetRedistURL, ExpandConstant('{app}\data\yy.dll'));
isxdl_SetOption('Updating', 'Updating to the latest DLL...');
isxdl_SetOption('Please wait...', 'Updating...');
isxdl_DownloadFiles(WizardForm.Handle);
end;
end;

How to get installation path during uninstall?

My idea is to offer the user the choice of installing the application either in {localappdata} or {commonappdata}, and that part works fine. However, I'm using custom Inno Setup skinning support, which requires a couple functions to get loaded during installation/uninstallation.
I have a DefaultAppDataFolder(): String function which returns the folder that the user chose (either common or local appdata one), and it works fine during installation. However, when I try to uninstall the app, it throws following error right upon execution:
Script error: Could not call proc
You can see that in the DefaultAppDataFolder() function I'm getting the uninstall directory in a bit shady way, extracting the file directory twice from the {UninstallExe} constant, maybe there is a better way to retrieve this?
Here is my script:
#define ApplicationName "MyApp"
#define ApplicationExe "app.exe"
#define ApplicationInstanceMutex "APPMUTEX"
#define InstallerFilename "install_app"
#define SkinName "Carbon.vsf"
[Setup]
AppName={#ApplicationName}
AppVerName={#ApplicationName}
DefaultDirName={code:DefaultAppDataFolder}
DefaultGroupName={#ApplicationName}
UninstallFilesDir={code:DefaultAppDataFolder}\uninstall
UninstallDisplayName={#ApplicationName}
Compression=lzma2
SolidCompression=yes
OutputDir=.\
DisableDirPage=yes
OutputBaseFilename={#InstallerFilename}
UninstallDisplayIcon={code:DefaultAppDataFolder}\{#ApplicationExe}
DisableProgramGroupPage=yes
AppMutex={#ApplicationInstanceMutex}
WizardImageFile=installer_images\installer-1.bmp
WizardSmallImageFile=installer_images\installer-2.bmp
[Files]
Source: "skins\VclStylesInno.dll"; DestDir: "{code:DefaultAppDataFolder}"; Flags: uninsneveruninstall ignoreversion
Source: "skins\{#SkinName}"; DestDir: "{code:DefaultAppDataFolder}"; Flags: ignoreversion
Source: "root_files\*.*"; DestDir: "{code:DefaultAppDataFolder}"; Flags: ignoreversion
Source: "client_files\*.*"; DestDir: "{code:DefaultAppDataFolder}"; Flags: ignoreversion
Source: "ssl_libs\*.*"; DestDir: "{code:DefaultAppDataFolder}"; Flags: ignoreversion
[Icons]
Name: "{group}\{#ApplicationName}"; Filename: "{code:DefaultAppDataFolder}\{#ApplicationExe}"; WorkingDir: "{code:DefaultAppDataFolder}"
Name: "{group}\Uninstall"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#ApplicationName}"; Filename: "{code:DefaultAppDataFolder}\{#ApplicationExe}"; Tasks: desktopicon
[Run]
Filename: "{code:DefaultAppDataFolder}\{#ApplicationExe}"; Description: "Launch {#ApplicationName}"; Flags: postinstall nowait runascurrentuser
[Tasks]
Name: commondir; Description: "&All users"; GroupDescription: "Install For:"; Flags: exclusive
Name: localdir; Description: "&Current user"; GroupDescription: "Install For:"; Flags: exclusive unchecked
Name: desktopicon; Description: "Create a &desktop icon"
[Code]
procedure LoadVCLStyleS(VClStyleFile: String); external 'LoadVCLStyleW#files:VclStylesInno.dll stdcall setuponly';
procedure UnLoadVCLStylesS; external 'UnLoadVCLStyles#files:VclStylesInno.dll stdcall setuponly';
procedure LoadVCLStyleU(VClStyleFile: String); external 'LoadVCLStyleW#{code:DefaultAppDataFolder}\VclStylesInno.dll stdcall uninstallonly';
procedure UnLoadVCLStylesU; external 'UnLoadVCLStyles#{code:DefaultAppDataFolder}\VclStylesInno.dll stdcall uninstallonly';
var
ApplicationUninstalled: Boolean;
WizardInitialized: Boolean;
function InitializeSetup(): Boolean;
var
C1: Integer;
begin
ExtractTemporaryFile('{#SkinName}');
LoadVCLStyleS(ExpandConstant('{tmp}\{#SkinName}'));
result := TRUE;
end;
procedure InitializeWizard();
begin
WizardInitialized := TRUE;
end;
procedure DeinitializeSetup();
begin
UnLoadVCLStylesS;
end;
function InitializeUninstall(): Boolean;
begin
LoadVCLStyleU(ExpandConstant('{code:DefaultAppDataFolder}\{#SkinName}'));
result := TRUE;
end;
procedure InitializeUninstallProgressForm();
begin
ApplicationUninstalled := TRUE;
end;
procedure DeinitializeUninstall();
begin
UnLoadVCLStylesU;
UnloadDLL(ExpandConstant('{code:DefaultAppDataFolder}\VclStylesInno.dll'));
if ApplicationUninstalled then
begin
DeleteFile(ExpandConstant('{code:DefaultAppDataFolder}\VclStylesInno.dll'));
RemoveDir(ExpandConstant('{code:DefaultAppDataFolder}'));
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
mres: integer;
begin
case CurUninstallStep of
usPostUninstall: begin
mres := MsgBox('Do you want to delete user data?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2)
if mres = IDYES then
begin
DelTree(ExpandConstant('{localappdata}\{#ApplicationName}'), TRUE, TRUE, TRUE);
DelTree(ExpandConstant('{userappdata}\{#ApplicationName}'), TRUE, TRUE, TRUE);
end;
end;
end;
end;
function DefaultAppDataFolder(Param: String): String;
begin
if IsUninstaller then
result := ExtractFileDir(ExtractFileDir(ExpandConstant('{uninstallexe}')))
else
if (WizardInitialized) and
(IsTaskSelected('localdir')) then
result := ExpandConstant('{localappdata}') + '\Programs\{#ApplicationName}'
else
result := ExpandConstant('{commonappdata}') + '\Programs\{#ApplicationName}';
end;
The error you got is not related to the uninstaller; you can narrow the problem down to this:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName=My Program
[Code]
procedure DoSomething;
external 'DoSomething#{code:GetLibPath}\MyLib.dll stdcall setuponly';
function GetLibPath(Value: string): string;
begin
Result := 'C:\ValidPathToLib';
end;
From the above script it seems that you cannot use scripted constants for imported DLL file names. And even delayed loading didn't workaround this limit. But for your case you can use just {app} path since your library is actually there (if I get your intention right):
...
procedure LoadVCLStyleU(VClStyleFile: string);
external 'LoadVCLStyleW#{app}\VclStylesInno.dll stdcall uninstallonly';
procedure UnLoadVCLStylesU;
external 'UnLoadVCLStyles#{app}\VclStylesInno.dll stdcall uninstallonly';
...

How to separate a Inno Setup script into multiple files?

I have two setup scripts that share common code. It is possible to refactor them?
One way of doing that is having a file for common code which will be referenced by each script.
Is this possible?
Depending on the version of InnoSetup you are using, you can use an include file. The example below uses three files (main.iss, code.iss, commonfiles.iss):
Main File:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "My Program"
#define MyAppVerName "My Program 1.5"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.exe"
[Setup]
AppName={#MyAppName}
AppVerName={#MyAppVerName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "C:\util\innosetup\Examples\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
#include "CommonFiles.iss"
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#MyAppName}}"; Flags: nowait postinstall skipifsilent
#include "code.iss"
CommonFiles.iss:
Source: "Common.DLL"; DestDir: "{app}"; Flags: ignoreversion
Code.iss:
[code]
function IsDotNET11Detected(): boolean;
// Indicates whether .NET Framework 1.1 is installed.
var
success: boolean;
install: cardinal;
begin
success := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v1.1.4322', 'Install', install);
Result := success and (install = 1);
end;
function InitializeSetup(): Boolean;
begin
if not IsDotNET11Detected then begin
MsgBox('This software requires the Microsoft .NET Framework 1.1.'#13#13
'Please use Windows Update to install this version,'#13
'and then re-run the setup program.', mbInformation, MB_OK);
Result := false;
end else
begin
MsgBox('Framework installed',mbInformation, MB_OK);
Result := true;
end
end;

Resources