Create desktop link Icon after the Run section of Inno Setup - inno-setup

Overview
My install process involves placing over 2GB of data on a disk. So I use Inno Setup, but I run 7ZIP to actually extract/install the files.
Issue
The issue I have is that it seems the desktop icon is being created before the [Run] section, so there is no icon to set the the desktop link. Is there a way around this? (I have tried both {src} and {app} as the folder to find the icon.)
CODE
[Run]
Filename: "{pf64}\7-zip\7zG.exe"; Parameters: "x ""{src}\GL.7z"" -o""{app}\"" * -r -aoa"; \
Flags: runascurrentuser
[Icons]
Name: "{group}\EGPL Watson Uninstall"; Filename: "{uninstallexe}"; WorkingDir: "{app}"
Name: "{commondesktop}\DashBoard"; \
Filename: "{app}\dashboard\node_modules\electron\dist\electron.exe"; \
WorkingDir: "{app}\dashboard"; IconFilename: "{src}\dashboard\build\configure.ico"; \
Parameters: "main.js"; AfterInstall: SetElevationBit('{commondesktop}\DashBoard.lnk')

A quick and dirty solution is to set ChangesAssociations:
[Setup]
ChangesAssociations=yes
It makes Windows Explorer refresh all icons after the installer finishes.
A clean solution is to create the icon only after the [Run] section using CreateShellLink:
[Run]
Filename: "{pf64}\7-zip\7zG.exe"; \
Parameters: "x ""{src}\GL.7z"" -o""{app}\"" * -r -aoa"; \
Flags: runascurrentuser; AfterInstall: CreateIcon
[Code]
procedure CreateIcon;
var
IconFileName: string;
begin
IconFileName := ExpandConstant('{commondesktop}\DashBoard.lnk');
CreateShellLink(
IconFileName, '',
ExpandConstant('{app}\dashboard\node_modules\electron\dist\electron.exe'),
'main.js', ExpandConstant('{app}\dashboard'),
ExpandContant('{app}\dashboard\build\configure.ico'), 0, SW_SHOWNORMAL);
SetElevationBit(IconFileName);
end;

Related

Using regasm with AnyCPU DLL for both 32 bit and 64 bit using Inno Setup

I have a C# COM DLL that has been compiled with the setting Any CPU.
At the moment I have put this into the script:
[Run]
Filename: "{dotnet40}\regasm.exe"; Parameters: "MSAToolsGMailClassLibrary.dll /codebase"; WorkingDir: "{app}"; Flags: runhidden
Filename: "{dotnet4064}\regasm.exe"; Parameters: "MSAToolsGMailClassLibrary.dll /codebase"; WorkingDir: "{app}"; Flags: runhidden; Check: IsWin64
[UninstallRun]
Filename: {dotnet40}\regasm.exe; Parameters: /u MSAToolsGMailClassLibrary.dll; WorkingDir: {app}; Flags: runhidden
Filename: {dotnet4064}\regasm.exe; Parameters: /u MSAToolsGMailClassLibrary.dll; WorkingDir: {app}; Flags: runhidden; Check: IsWin64;
Since there is only one file (but my installer installs my application in both 32 bit and 64 bit) have I done the right thing here by putting it twice?

Open HTML page from Inno Setup post install Run section entry

Is it possible to turn these [run] entries into internet hyper-links instead?
Filename: "{win}\hh.exe"; \
Parameters: "{app}\CommunityTalks.chm::/CommunityTalks.htm"; \
WorkingDir: "{app}"; \
Flags: nowait postinstall runmaximized; \
Description: "{cm:ShowOverview}"
Filename: "{win}\hh.exe"; \
Parameters: "{app}\CommunityTalks.chm::/revisions.htm"; \
WorkingDir: "{app}"; \
Flags: nowait postinstall runmaximized; \
Description: "{cm:ViewChangeHistory}"
I have managed to update my [icons] section of the script for the same two items:
Name: "{group}\Public Talks Help"; \
Filename: "https://help-pts.publictalksoftware.co.uk/pts-overview.html"
Name: "{group}\Revision History"; \
Filename: "https://help-pts.publictalksoftware.co.uk/pts-revision-history.html"
But I can't work out what the [run] counterparts should look like.
Update
So I tried:
// AJT v19.0.0 Display the Overview help topic (now uses online link)
Filename: "https://help-pts.publictalksoftware.co.uk/pts-overview.html"; \
Flags: nowait postinstall runmaximized; \
Description: "{cm:ShowOverview}"
// AJT v19.0.0 Display the Revision History help topic (now uses online link)
Filename: "https://help-pts.publictalksoftware.co.uk/pts-revision-history.html"; \
Flags: nowait postinstall runmaximized; \
Description: "{cm:ViewChangeHistory}"
And I encounter an error during install:
To open a link, you need to use shellexec flag.
Filename: "https://www.example.com/"; \
Flags: shellexec postinstall runmaximized; \
Description: "Show Overview"
With shellexec, nowait is implicit, so I have removed it.
runmaximized will probably have little effect, as the link will typically open in a new tab of an existing browser window.
Note that when opening a link from an elevated (installer) process, there's often a concern that the browser starts elevated too, what can be a security issue. Brief testing shows that the shellexec runs browser non-elevated. But I cannot tell if it is reliable.
See this topic for other solutions:
How to open a web site after uninstallation in non-elevated mode?

Use both 32-bit and 64-bit version of rundll32.exe in Inno Setup

I want to convert theses two lines that I have in a batch file to Inno Setup [Run] section:
%windir%\SysWOW64\rundll32.exe "%~dp0my32.dll",RegDll
%windir%\system32\rundll32.exe "%~dp0my64.dll",RegDll
So I want something like this (but working):
[Run]
Filename: "{sys}\rundll32.exe"; Parameters: ""{code:GetDir|0}\my64.dll",RegDll"; WorkingDir: "{code:GetDir|0}"; StatusMsg: "Registering Module..."; MinVersion: 0.0,5.0; Flags: runhidden runascurrentuser
Filename: "{syswow64}\rundll32.exe"; Parameters: ""{code:GetDir|0}\my32.dll",RegDll"; WorkingDir: "{code:GetDir|0}"; StatusMsg: "Registering Module..."; MinVersion: 0.0,5.0; Flags: runhidden runascurrentuser
Your code is correct in 64-bit install mode, i.e. if you have ArchitecturesInstallIn64BitMode set:
[Setup]
ArchitecturesInstallIn64BitMode=x64
In 32-bit install mode, Inno Setup, being 32-bit application, will get redirected to C:\WINDOWS\SysWOW64, when it tries to access C:\Windows\System32. So effectively, both sys and syswow64 map to the same [32-bit] folder (C:\WINDOWS\SysWOW64).
You can override that (if you do not want to switch to 64-bit install mode) by using 64bit flag:
[Run]
Filename: "{sys}\rundll32.exe"; Parameters: """{code:GetDir|0}\my64.dll"",RegDll"; \
WorkingDir: "{code:GetDir|0}"; StatusMsg: "Registering Module..."; \
MinVersion: 0.0,5.0; Flags: runhidden runascurrentuser; Flags: 64bit;
Filename: "{sys}\rundll32.exe"; Parameters: """{code:GetDir|0}\my32.dll"",RegDll"; \
WorkingDir: "{code:GetDir|0}"; StatusMsg: "Registering Module..."; \
MinVersion: 0.0,5.0; Flags: runhidden runascurrentuser; Flags: 32bit;

Deleting and unregistering DLL files during install using Inno Setup

In my [Files] section I have the following:
; Database password decryption (for PTS importing)
Source: "..\..\..\PTSTools\PTSTools\bin\x86\Release\PTSTools.dll"; \
DestDir: "{app}"; \
DestName: "PTSTools_x86.dll"; Flags: ignoreversion
Source: "..\..\..\PTSTools\PTSTools\bin\x64\Release\PTSTools.dll"; \
DestDir: "{app}"; \
DestName: "PTSTools_x64.dll"; Flags: ignoreversion; Check: IsWin64
In the [Run] section I have:
Filename: "{dotnet40}\regasm.exe"; Parameters: "PTSTools_x86.dll /codebase"; \
WorkingDir: "{app}"; Flags: runhidden
Filename: "{dotnet4064}\regasm.exe"; Parameters: "PTSTools_x64.dll /codebase"; \
WorkingDir: "{app}"; Flags: runhidden; Check: IsWin64
Finally, in the [UninstallRun] section I have:
Filename: {dotnet40}\regasm.exe; Parameters: /u PTSTools_x86.dll; \
WorkingDir: {app}; \
Flags: runhidden
Filename: {dotnet4064}\regasm.exe; Parameters: /u PTSTools_x64.dll; \
WorkingDir: {app}; \
Flags: runhidden; Check: IsWin64;
Now, in this version of my program I have consolidated the functionality of these two DLL files into another set of DLL files:
Source: "..\..\..\MSAToolsLibrary\MSAToolsLibrary\bin\x86\Release\MSAToolsLibrary.dll"; \
DestDir: "{app}"; DestName: "MSAToolsLibrary_x86.dll"; Flags: ignoreversion
Source: "..\..\..\MSAToolsLibrary\MSAToolsLibrary\bin\x64\Release\MSAToolsLibrary.dll"; \
DestDir: "{app}"; DestName: "MSAToolsLibrary_x64.dll"; Flags: ignoreversion; \
Check: IsWin64
As a result, the PTSTool DLL files are no longer required. Now, I know I can simply delete them if they exist:
[InstallDelete]
Type: files; Name: "{app}\PTSTools_x64.dll"
Type: files; Name: "{app}\PTSTools_x86.dll"
But as far as I am aware this will not trigger the unregistering of the DLL files as is done in [UninstallRun].
How can I do this? Delete and unregister the DLL files (if they exist) during the install?
I do not think you can implement this easily using the standard sections.
A [Run] entry happens only after [InstallDelete]. While you need it the other way around to first unregister, before you delete a DLL.
So you need Pascal scripting.
Either add BeforeInstall parameter to [InstallDelete] and unregister the DLL programmaticaly.
Or add AfterInstall parameter to [Run] and delete the DLL programmatically.
The latter is less work for you, as you already know how to use [Run] to (un)register.
[Run]
Filename: {dotnet40}\regasm.exe; Parameters: /u PTSTools_x86.dll; \
WorkingDir: {app}; \
Check: FileExists(ExpandConstant('{app}\PTSTools_x86.dll')); \
AfterInstall: DoDeleteFile(ExpandConstant('{app}\PTSTools_x86.dll')); \
Flags: runhidden
Filename: {dotnet4064}\regasm.exe; Parameters: /u PTSTools_x64.dll; \
WorkingDir: {app}; \
Check: IsWin64 and FileExists(ExpandConstant('{app}\PTSTools_x64.dll')); \
AfterInstall: DoDeleteFile(ExpandConstant('{app}\PTSTools_x64.dll')); \
Flags: runhidden
[Code]
{ Cannot use built-in DeleteFile directly in AfterInstall as it's a function,
{ not a procedure. And this way we can add some error handling too. }
procedure DoDeleteFile(FileName: string);
begin
if DeleteFile(FileName) then
begin
Log(Format('"%s" deleted', [FileName]));
end
else
begin
MsgBox(Format('Failed to delete "%s"', [FileName]), mbError, MB_OK);
end;
end;

Error: Missing closing quote on parameter "Name"

At compile time, Inno keeps saying there was an error:
Line: 81
Error: Missing closing quote on parameter "Name"
but I don't see anything wrong. It points to the line just below [icons]
[Files]
Source: "{#SOURCEDIR}\Debug\myapplication.exe"; DestDir: {app}; Flags: ignoreversion
Source: "{#SOURCEDIR}\Debug\aDllFile.dll"; DestDir: {app}; Flags: ignoreversion
Source: "{#SOURCEDIR}\Debug\another.aDllFile.dll"; DestDir: {app}; Flags: ignoreversion
Source: "{#SOURCEDIR}\Debug\and.another.aDllFile.dll"; DestDir: {app}; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{#APPTITLE}"; Filename: "{app}\{#APPEXENAME}"
Name: "{group}\{cm:ProgramOnTheWeb,{#APPTITLE}}"; Filename: "{#APPURL}"
Name: "{group}\{cm:UninstallProgram,{#APPTITLE}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#APPTITLE}"; Filename: "{app}\{#APPEXENAME}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#APPTITLE}"; Filename: "{app}\{#APPEXENAME}"; Tasks: quicklaunchicon
Name: "{userstartup}\{#APPTITLE}"; Filename: "{app}\{#APPEXENAME}"; IconFilename: "{app}\{#APPEXENAME}";
[Run]
;Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, ""&"", ""&&"")}}"; Flags: nowait RunHidden SkipIfDoesntExist; Parameters: exit; WorkingDir: {app};
Filename: {app}\{#APPEXENAME}; Description: "{cm:LaunchProgram,{#StringChange(APPNAME, "noupdate", "&&")}}"; Flags: nowait postinstall skipifsilent
[Messages]
WelcomeLabel1=Welcome to the Setup Wizard for%n[name]
WelcomeLabel2=Salve! This application will install [name/ver] on your computer. You do not need administrator rights to do this.%n%nIf you would close your other applications before continuing, it would be mighty nice of you.
ExitSetupMessage=Hey! I'm not finished installing!%n If you exit now, the program will not be installed.%n%nHowever, you can always run the Setup again some other time if you wish to complete the installation.%n%nDo you still want to exit?
InfoBeforeLabel=Just a few little notes about {#APPTITLE}...
InfoBeforeClickLabel=When you are ready to continue the Installation, just click Next.
SelectTasksDesc=Just a few little tidbits, if you like them...
[note]
I can't believe this question was viewed 1003 times and noone gave me a vote!
Okay, I figured it out. One of my definitions was failing. It was supposed to extract the file_description from the target executable's resource.
#define APPTITLE GetStringFileInfo("C:\sourcepath\myapplication.exe", FILE_DESCRIPTION)
There was a ' in the File Description! And that caused Inno to offest all of its quotation marks.
Here is what Dee Earley at the Inno forum told me:
Why should it escape it? It doesn't know what it needs to escape it for, it's "just a string". You should escape it for it's output when needed using StringChange() or just quoting it properly. '

Resources