How to handle the .msi file with Inno Setup? - installation

I have this following code with Inno Setup.
But how can I apply this similar function to .msi file?
msiexec /I "\package\file.msi" /qb? How?
procedure AfterMyProgInstall(S: String);
var
ErrorCode: Integer;
begin
{MsgBox('Please wait the libraries are getting installed, ' +
'without the libraries it wont work.', mbInformation, MB_OK);}
ExtractTemporaryFile(S);
{SW_SHOW, SW_SHOWNORMAL, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE, SW_HIDE}
ShellExec('', ExpandConstant('{app}\package\' + S), '', '', SW_SHOWNORMAL,
ewWaitUntilTerminated, ErrorCode);
end;

Try this:
ShellExec('', 'msiexec.exe',
ExpandConstant('/I "{tmp}\package\file.msi" /qb'),
'', SW_SHOWNORMAL, ewWaitUntilTerminated, ErrorCode);
Or:
[Files]
Source: file.msi; DestDir: {tmp}; Flags: deleteafterinstall;
[Run]
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\file.msi"" /qb"; WorkingDir: {tmp};

Note that: I'm using Inno Setup 5.5.3 on Windows 7, and that this code
is for the Inno Setup script in the run section. With this code you can
run msi files without any problems. Here is the code:
[Run]
Filename: `{src}\PhysX.msi;` Description: Nvidia PhysX; Verb: open; Flags: shellexec postinstall waituntilterminated runascurrentuser skipifsilent

Building on the answer #kobik gave. I had to include the '.exe' in the Filename.
Like so:
if not ShellExec('', 'msiexec.exe', ExpandConstant('{tmp}\package\file.msi'),
'', SW_SHOWNORMAL, ewWaitUntilTerminated, ErrorCode)
then
MsgBox('Msi installer failed to run!' + #13#10 + ' ' +
SysErrorMessage(ErrorCode), mbError, MB_OK);

Although kobik's option to use "msiexec.exe /i" in Run section generally works, we faced a problem of admin right downgrade with it:
[Run]
Filename: "msiexec.exe"; Parameters: "/i ""{tmp}\file.msi"" /qb"; WorkingDir: {tmp};
When msiexec.exe /i file.msi runs this way it requests the admin rights with UAC (as expected, it is really required in our case). But somewhere in the middle of this installation part when "file.msi" is trying to start a windows service it appeared to be right-downgraded and have not enough privileges to start windows service.
However when it's launched via shellexec it goes ok without this problem. So this is how it worked to me:
[Run]
Filename: "{tmp}\file.msi"; Flags: skipifsilent shellexec waituntilterminated hidewizard;

Related

Downloading file with Inno Setup only when user chooses to

Question: I’d like to know how to script to download a second file which is a zip but initially give a choice between two zip files; download, unzip and delete the zip. The zip files each have different names but the contents have a different name to the zips (each the same name); no renaming required. This question is a little similar to Apply Download file condition in inno-setup
The files in question are downloaded via the SourceForge website. The programs (clones) these files are intended for are either not listed on SF or have changed purpose.
After fixing the PChar bug: InnoTools Downloader not working with Inno 5.5 I'm now able to re-use this Inno Setup script from 2011 but want to expand it slightly but struggling to.
#include ReadReg(HKEY_LOCAL_MACHINE,'Software\Sherlock Software\InnoTools\Downloader','ScriptPath','');
[Code]
procedure InitializeWizard();
begin
itd_init;
{ Set download source.. }
itd_addfile('http://www.example.com/Textfile.txt', ExpandConstant('{tmp}\Textfile.txt'));
itd_setoption('UI_AllowContinue','1');
itd_setoption('UI_DetailedMode','1');
{ Start the download after the "Ready to install" screen is shown }
itd_downloadafter(wpReady);
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then { Lets install the downloaded files }
begin
FileCopy(ExpandConstant('{tmp}\Textfile.txt'), ExpandConstant('{userappdata}\program_name\Textfile.txt'), false);
end;
end;
Working code based on the answer:
#pragma include __INCLUDE__ + ";" + "c:\lib\InnoDownloadPlugin"
[Setup]
...
CreateUninstallRegKey=no
#include <idp.iss>
...
[Types]
Name: full; Description: "Full installation"
Name: compact; Description: "Compact installation"
Name: custom; Description: "Custom installation"; Flags: iscustom
[Components]
Name: abc; Description: "C File"; Types: full compact custom; Flags: fixed
Name: hlnj; Description: "HL (Recommended)"; Types: custom; Flags: exclusive
Name: hnj; Description: "HF"; Types: custom; Flags: exclusive
[Files]
Source: "{tmp}\text.net"; DestDir: "{userappdata}\ccc"; Flags: external; Components: abc
Source: "{tmp}\HLNJ.zip"; DestDir: "{userappdata}\ccc"; Flags: external; Components: hlnj
Source: "{tmp}\HNJ.zip"; DestDir: "{userappdata}\ccc"; Flags: external; Components: hnj
[Code]
procedure InitializeWizard;
begin
idpAddFileComp('http://www.example.com/text.net', ExpandConstant('{tmp}\text.net'), 'abc');
idpAddFileComp('http://www.example.com/SecurityUpdates/HLNJ.zip', ExpandConstant('{tmp}\HLNJ.zip'), 'hlnj');
idpAddFileComp('http://www.example.com/SecurityUpdates/HNJ.zip', ExpandConstant('{tmp}\HNJ.zip'), 'hnj');
idpDownloadAfter(wpReady);
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
FileCopy(ExpandConstant('{tmp}\text.net'), ExpandConstant('{userappdata}\ccc\text.net'), false);
FileCopy(ExpandConstant('{tmp}\HLNJ.zip'), ExpandConstant('{userappdata}\ccc\HLNJ.txt'), false);
FileCopy(ExpandConstant('{tmp}\HNJ.zip'), ExpandConstant('{userappdata}\ccc\HNJ.txt'), false);
end;
end;
Only after posting my answer, I've noticed that despite you tagging the question inno-download-plugin, you are actually using InnoTools Downloader. Do not – InnoTools Downloader is dead and unmaintained.
Also note that the Inno Setup 6.1 has a built-in support for downloads. With that API, the solution will be easier, but different than what is shown below to IDP. See Inno Setup: Install file from Internet.
In the examples folder of Inno Download Plugin installation, there are components1.iss and components2.iss examples.
The first shows how to use idpAddFileComp to conditionally download a file, when a component is selected.
I'm re-posting a full example:
; Uncomment one of following lines, if you haven't checked "Add IDP include path to ISPPBuiltins.iss" option during IDP installation:
;#pragma include __INCLUDE__ + ";" + ReadReg(HKLM, "Software\Mitrich Software\Inno Download Plugin", "InstallDir")
;#pragma include __INCLUDE__ + ";" + "c:\lib\InnoDownloadPlugin"
[Setup]
AppName = My Program
AppVersion = 1.0
DefaultDirName = {pf}\My Program
DefaultGroupName = My Program
OutputDir = userdocs:Inno Setup Examples Output
#include <idp.iss>
[Types]
Name: full; Description: "Full installation"
Name: compact; Description: "Compact installation"
Name: custom; Description: "Custom installation"; Flags: iscustom
[Components]
Name: app; Description: "My Program"; Types: full compact custom; Flags: fixed
Name: help; Description: "Help files"; Types: full
Name: src; Description: "Source code"; Types: full
[Files]
Source: "{tmp}\app.exe"; DestDir: "{app}"; Flags: external; ExternalSize: 1048576; Components: app
Source: "{tmp}\help.chm"; DestDir: "{app}"; Flags: external; ExternalSize: 1048576; Components: help
Source: "{tmp}\src.zip"; DestDir: "{app}"; Flags: external; ExternalSize: 1048576; Components: src
[Icons]
Name: "{group}\My Program"; Filename: "app.exe"; Components: app
Name: "{group}\Help file"; Filename: "help.chm"; Components: help
Name: "{group}\{cm:UninstallProgram,My Program}"; Filename: "{uninstallexe}"
[Code]
procedure InitializeWizard;
begin
idpAddFileComp('http://127.0.0.1/app.exe', ExpandConstant('{tmp}\app.exe'), 'app');
idpAddFileComp('http://127.0.0.1/help.chm', ExpandConstant('{tmp}\help.chm'), 'help');
idpAddFileComp('http://127.0.0.1/src.zip', ExpandConstant('{tmp}\src.zip'), 'src');
idpDownloadAfter(wpReady);
end;
Caveat: The component name passed to idpAddFileComp must be in lowercase (the actual component name can use uppercase).
Inno Setup 6.1.2 has new DownloadTemporaryFile support function to download files without using a third-party tool:
Supports HTTPS (but not expired or self-signed certificates) and HTTP.
Redirects are automatically followed and proxy settings are automatically used.
Safe to use from services unlike existing third-party tools.
Supports SHA-256 hash checking of the downloaded file.
Supports basic authentication.
I added this answer because even the IDP plugin referred in the accepted answer was last updated in 2016 and did not work for me now and I had to change to the new function provided by Inno Setup 6.1.2.

Inno Setup always installs into admin's AppData directory

I want to store my app in the current user's AppData directory to avoid problems with permissions we had when auto-updating our app (when it's stored in Program Files). We don't give the user the option of where to install the app. We've had complaints from non-admin users that the installer stores the app in the admin's AppData directory (after UAC of course), instead of the current user's AppData directory, which then prevents the app from running in the future.
Firstly, I had DefaultDirName={userappdata}\{#MyAppName}. Then I tried DefaultDirName={commonappdata}\{#MyAppName}. Then I tried that along with PrivilegesRequired=lowest and even as PrivilegesRequired=none as the Make InnoSetup installer request privileges elevation only when needed question suggested.
This is my script as of right now in case I'm missing something obvious:
; Script generated by the Inno Setup Script Wizard.
;SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "Teamwork Chat"
#define MyAppVersion "0.10.0"
#define MyAppPublisher "Digital Crew, Ltd."
#define MyAppURL "http://www.teamwork.com/"
#define MyAppExeName "TeamworkChat.exe"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{0F063485-F5AF-4ADE-A9F9-661AB3BAA661}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={userappdata}\{#MyAppName}
DisableDirPage=yes
DefaultGroupName={#MyAppName}
OutputDir=E:\chat-client\dist
OutputBaseFilename={#MyAppName}_for_Windows32_Installer-{#MyAppVersion}
SetupIconFile=E:\chat-client\icons\teamwork_chat.ico
WizardImageFile=E:\chat-client\icons\chatWizardImageFile.bmp
Compression=lzma
SolidCompression=yes
PrivilegesRequired=none
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "E:\chat-client\dist\TeamworkChat\win32\TeamworkChat.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\ffmpegsumo.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\icudtl.dat"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\libEGL.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\libGLESv2.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\chat-client\dist\TeamworkChat\win32\nw.pak"; DestDir: "{app}"; Flags: ignoreversion
; 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,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
Edit
I've changed two options but still no luck;
PrivilegesRequired=lowest
...
[Icons]
...
Name: "{userdesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Edit 2:
I've added the runasoriginaluser flag and generated a new AppId (GUID) but still no luck;
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent runasoriginaluser
Edit 3:
I've created a simple GitHub repository with the source files and Inno script.
Edit 4:
I had been testing on Windows 8.1. It seems to work when compiled on Windows 7, and ran on Windows 8, but not when compiled on 8 and ran on 8.
Edit 5:
It's solved now but to clear things up regarding Edit 4, it wasn't working only on my machine. It worked on other Windows 8 machines. Must've been some weird caching or something (even though I changed the AppId).
From the wording of your question and if I am understanding you correctly, it sounds like this is because you are "validating with an admin account for the install to run." If this is the case and you are entering a different account (from that which you are logged in with) at the UAC prompt, the current user then actually becomes the Administrator account you just entered at the UAC prompt and not the account you are logged in with. Therefore, as long as you are being asked to elevate the installation using UAC, it will not end up in the logged in user's AppData directory.
What you may need to do is use the runasoriginaluser function, which will use the logged in user credentials instead of the account you entered at the UAC prompt, or find what is causing the UAC elevation prompt.
See also Inno Setup Creating registry key for logged in user (not admin user).
The MSDN documentation on Installation Context may also be useful.
It should work with PrivilegesRequired=lowest. And it's the correct approach. If it does not, we want to see a log file.
The lowest will make the installer run within context of the current unprivileged user. Hence all constants, like {userappdata}, {userdesktop}, etc, will refer to the current user.
Anyway, to answer your question, you can use the code below.
But that's just for special situations, when the installer really needs administrator privileges (e.g. to register some system DLL), but still needs to deploy files for the original user. Like here: Inno Setup - Register components as an administrator.
[Files]
Source: "MyProg.exe"; DestDir: "{code:GetAppData}"
[Code]
var
AppDataPath: string;
function GetAppData(Param: string): string;
begin
Result := AppDataPath;
end;
function InitializeSetup(): Boolean;
var
Uniq: string;
TempFileName: string;
Cmd: string;
Params: string;
ResultCode: Integer;
Buf: AnsiString;
begin
AppDataPath := ExpandConstant('{userappdata}');
Log(Format('Default/Fallback application data path is %s', [AppDataPath]));
Uniq := ExtractFileName(ExpandConstant('{tmp}'));
TempFileName :=
ExpandConstant(Format('{commondocs}\appdata-%s.txt', [Uniq]));
Params := Format('/C echo %%APPDATA%% > %s', [TempFileName]);
Log(Format('Resolving APPDATA using %s', [Params]));
Cmd := ExpandConstant('{cmd}');
if ExecAsOriginalUser(Cmd, Params, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and
(ResultCode = 0) then
begin
if LoadStringFromFile(TempFileName, Buf) then
begin
AppDataPath := Trim(Buf);
Log(Format('APPDATA resolved to %s', [AppDataPath]));
end
else
begin
Log(Format('Error reading %s', [TempFileName]));
end;
DeleteFile(TempFileName);
end
else
begin
Log(Format('Error %d resolving APPDATA', [ResultCode]));
end;
Result := True;
end;
More similar questions:
Inno Setup Using {localappdata} for logged in user
Inno Setup - puts user files in admin documents

I want to create setup file with Inno Setup

I need help with Inno Setup. First of all I want to sorry about my english. I hope you understand me.
I have this script:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "My software - BETA"
#define MyAppVersion "1.5"
#define MyAppExeName "My software.exe"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{009E8058-565E-43F7-BEAD-34E283BCA6F4}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
LicenseFile=D:\My software\EULA.rtf
OutputBaseFilename=My software - 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: "D:\My software\My software.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "D:\My software\settings.txt"; DestDir: "{userappdata}\My software"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
The setup works but I want to add several options to the setup:
1) If the software is already installed then I want that will be an option that give the usere the ability to choose whether to overwrite the previous settings..
something like checkbox: "Don't overwrite the previous settings"
and in by default the setup will not overwrite the previous settings.
2) In the uninstaller I want the option: "Remove also the settings" (something like that) and by default this option is unchecked
3) I want that the option "Create a desktop icon" will always be checked by default.
I noticed that this option is checked by default only if the icon is already created before.
Thanks for helpers!
Gil.
Answers for your question:
1-If you are installing a application which is already install it should give user uninstalling
option.To keep Previous setting you can use Flags: onlyifdoesntexist for [Files], or
Flags: createvalueifdoesntexist for [Registry].
2-Put the following code in [Code] section,it should give user to removeing setting option.
[Code]
procedure CurUninstallStepChanged (CurUninstallStep: TUninstallStep);
var
mres : integer;
begin
case CurUninstallStep of
usPostUninstall:
begin
mres := MsgBox('Do you want to Remove Settings?', mbConfirmation, MB_YESNO or MB_DEFBUTTON2)
if mres = IDYES then
DelTree(ExpandConstant('{userdocs}\Myapp'), True, True, True);
end;
end;
end;
3-If you want the icon task Will be checked then remove the Flags: unchecked part from [Task] section.

Change the default name of an Inno Setup uninstaller to avoid naming conflicts

I need to install a couple of installers in the same directory so it conflicts with the Inno Setup uninstaller name unins000.exe and unins000.dat
Is there a way to change the default name of an Inno Setup uninstaller?
No. 'unins' is hard-coded in the name generation procedure of the executable, data and msg files, in GenerateUninstallInfoFilename' procedure in 'install.pas' of inno-setup sources.
GenerateFilenames sub procedure has this:
BaseFilename := AddBackslash(BaseDir) + Format('unins%.3d', [I]);
UninstallExeFilename := BaseFilename + '.exe';
..
Where 'I' is an integer and 'BaseDir' is derived from UninstallFilesDir which you can change.
Just dealt with this myself. You shouldn't move the uninstaller executable itself around, for reasons Martin Prikryl pointed out. But I agree it is unsatisfying to have a bunch of numbered uninstallers sitting in a directory with no obvious means of telling which is which.
There is a solution using the facilities Inno Setup provides. In the [Setup] section:
[Setup]
...
UninstallFilesDir=Uninstall\exe\{#NAME_OF_APP}
...
Then in the [Dirs] section:
[Dirs]
...
Name: Uninstall\exe; Attribs: hidden;
Name: Uninstall\exe\{#NAME_OF_APP}; Attribs: hidden;
...
And finally you create named shortcuts in [Icons] that point to the uninstallers which will always have the same name because you've sequestered them:
[Icons]
...
Name: Uninstall\{#NAME_OF_UNINSTALLER}; Filename: Uninstall\exe\{#NAME_OF_APP}\unins000.exe
...
This leaves references in the OS to the uninstallers alone, hides the confusing executable names in a folder the user won't usually see but can still access, and provides named, descriptive shortcuts that can all live in the same folder. You can also give the shortcuts a good icon. For good measure, maybe drop an extra README in the \exe directory to explain what is going on just in case someone gets nosey (they will, naturally).
Inno does this automatically when it detects a different application being installed into the same directory (based on a different AppID). There should be no need to go behind its back and rename the uninstaller files.
Well, while it's still not possibly to nativelly change the uninstaller name then I'll use Batch commands at the run section to rename the uninstaller and to do the same in the uninstaller registry paths:
[Run]
Filename: {cmd}; Parameters: "/C Move ""{app}\unins000.exe"" ""{app}\Uninstallers\{#ApplicationName} - uninstall.exe"""; StatusMsg: Installing {#ApplicationName}...; Flags: RunHidden WaitUntilTerminated
Filename: {cmd}; Parameters: "/C Move ""{app}\unins000.dat"" ""{app}\Uninstallers\{#ApplicationName} - uninstall.dat"""; StatusMsg: Installing {#ApplicationName}...; Flags: RunHidden WaitUntilTerminated
Filename: REG.exe; Parameters: "ADD ""HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Windows 8 ContextMenu - {#ApplicationName}_is1"" /V ""UninstallString"" /T ""REG_SZ"" /D ""\""{app}\Uninstallers\{#ApplicationName} - uninstall.exe\"""" /F"; StatusMsg: Installing {#ApplicationName}...; Flags: RunHidden WaitUntilTerminated
Filename: REG.exe; Parameters: "ADD ""HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Windows 8 ContextMenu - {#ApplicationName}_is1"" /V ""QuietUninstallString"" /T ""REG_SZ"" /D ""\""{app}\Uninstallers\{#ApplicationName} - uninstall.exe\"" /SILENT"" /F"; StatusMsg: Installing {#TipName}...; Flags: RunHidden WaitUntilTerminated
This is similar to Elektrostudios' answer, and is what worked for me:
Filename: {cmd}; Parameters: "/C Mkdir ""{app}\Uninstallers\{#MyAppName}"""; Flags: RunHidden WaitUntilTerminated
Filename: {cmd}; Parameters: "/C Move ""{app}\unins000.exe"" ""{app}\Uninstallers\{#MyAppName} - uninstall.exe"""; StatusMsg: Installing {#MyAppName}...; Flags: RunHidden WaitUntilTerminated
Filename: {cmd}; Parameters: "/C Move ""{app}\unins000.dat"" ""{app}\Uninstallers\{#MyAppName} - uninstall.dat"""; StatusMsg: Installing {#MyAppName}...; Flags: RunHidden WaitUntilTerminated
Filename: {cmd}; Parameters: "/C Move ""{app}\unins000.msg"" ""{app}\Uninstallers\{#MyAppName} - uninstall.msg"""; StatusMsg: Installing {#MyAppName}...; Flags: RunHidden WaitUntilTerminated
Filename: REG.exe; Parameters: "ADD ""HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Windows 8 ContextMenu - {#MyAppName}_is1"" /V ""UninstallString"" /T ""REG_SZ"" /D ""\""{app}\Uninstallers\{#MyAppName} - uninstall.exe\"""" /F"; StatusMsg: Installing {#MyAppName}...; Flags: RunHidden WaitUntilTerminated
Filename: REG.exe; Parameters: "ADD ""HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Windows 8 ContextMenu - {#MyAppName}_is1"" /V ""QuietUninstallString"" /T ""REG_SZ"" /D ""\""{app}\Uninstallers\{#MyAppName} - uninstall.exe\"" /SILENT"" /F"; StatusMsg: Installing {#MyAppName}...; Flags: RunHidden WaitUntilTerminated
Using Windows 7, I discovered that the "Move" command wouldn't work unless I had somewhere to move the files to first, meaning that I had to add the mkdir line at the top. Also, the uninstaller wouldn't work without the .msg file moved as well, so I followed the pattern and added that line too.
I didn't bother to change "Windows 8" to "Windows 7" but it didn't make any difference, so I'm leaving it alone. If there's a problem with that I'm unaware of, I'm sure someone will indicate such in a comment.
{#MyAppName} is, of course, the constant defined at the top of the ISS file declaring the name of the application. Your constant may be defined differently, so you'll need to change it to match where necessary.
Inno Setup does not offer any way to let you name (or rename) the uninstaller. Inno Setup takes care of naming conflicts on its own.
Also note that when you try to rename the uninstaller manually (like some answers here do), you break the reference to the uninstaller in Add or remote application in Control Panel.
Even if you fix the reference, there's another problem. When you upgrade later, the new installer won't find logs of the previous installer and won't be able to merge them. Consequently a future uninstallation won't completely remove the application. See the Appending to Existing Uninstall Logs in Inno Setup documentation.

Inno Setup drivers install

I cannot find a way for Inno Setup to install drivers.
I have checked these questions here:
Inno setup: install drivers with rundll32 or dpinst?
How to run a file before setup with Inno Setup and How to install DirectX redistributable from Inno-setup?.
My code is like this:
[Files]
Source: "drivers\dpinst64.exe"; DestDir: "{app}\drivers"; Check: Is64BitInstallMode; Components: drivers;
[code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
ResultCode: Integer;
begin
if IsWin64 then begin
ExtractTemporaryFile('drivers\dpinst64.exe');
Exec(ExpandConstant('{tmp}\dpinst64.exe'), '-install "' + ExpandConstant('{tmp}') + '"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
end;
1) Right now my installer crashes because it cannot find drivers\dpinst64.exe when extracting the temporary file.
2) Before this i tried simply running the .exe in [run] but nothing happened. When the .exe was run, the run lasted 5 miliseconds and then I got the -2147483648 return code. Exec(ExpandConstant('{win}\notepad.exe'), '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) runs just fine in InitializeSetup.
What could be the problem here? Is there another better way to initiate driver instalation right before the installer finishes its work?
If you try this, what will happen?
What is the parameter to install dpinst64.exe? From your attempt, it looks like this (assuming that {tmp} ends up being Windows %TEMP%):
%TEMP%\dpinst64.exe -install "%TEMP%"
Is it the correct statement to install dpinst64.exe?
[Files]
Source: "drivers\dpinst64.exe"; DestDir: "{tmp}"; Check: Is64BitInstallMode; Components: drivers;
[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
ResultCode: Integer;
begin
if IsWin64 then begin
ExtractTemporaryFile('dpinst64.exe');
Exec(ExpandConstant('{tmp}\dpinst64.exe'), '-install "' + ExpandConstant('{tmp}') + '"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
end;
I assume that the driver dpinst64.exe is the only file in the drivers folder of your source that needs to be distributed in your installer. If it is not the case, then you should type as follows:
[Files]
Source: "drivers\*"; DestDir: "{tmp}"; Check: Is64BitInstallMode; Components: drivers;
To answer your questions:
1. You should use ExtractTemporaryFile('dpinst64.exe'); instead of ExtractTemporaryFile('drivers\dpinst64.exe');.
2. For the failure to run the DPINST64.EXE, you might need to extract the INF, SYS, and any other dependencies for the driver into the directory where DPINST64.EXE. You would need multiple ExtractTemporaryFile statements to extract multiple files.
keep in mind that dpinst is software first meaning it doesn't actually install the device until it is plugged in.

Resources