Adding custom icon in inno setup [duplicate] - inno-setup

This question already has an answer here:
How to create a desktop icon with Inno Setup
(1 answer)
Closed 2 years ago.
I wish to add a custom Desktop icon to my executable in Inno Setup.
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}";
[Files]
Source: C:\icons\javelin.ico; DestDir: {app}; Flags: dontcopy;
[Icons]
Name: "{userdesktop}\{#MyAppName}"; Filename: "{code:GetDir}\source\app\{#MyAppExeName}"; Tasks: desktopicon; IconFilename: "{tmp}\javelin.ico";
function InitializeSetup(): Boolean;
begin
ExtractTemporaryFile('javelin.ico');
Result := True;
end;
The above code is adding the icon on desktop but when the user restarts the machine the javelin image will disappears only file's default icon will remain.

It is because you use Temp Folder for your icon. if you want your icon path to be available all the time you should use some permanent path. for example copy it to {app} folder or some other path.

Related

Setup is "unresponsive" at startup if I compile it with compression [duplicate]

My Installer created with Inno Setup is about 850 MB in size containing about 7000 files and 890 Folders to an uncompressed size of 1.98 GB.
When starting the install process, after the Windows UAC Dialog shows up, the Installer is sitting with an empty icon in the Taskbar for approx. 45 seconds before the Welcome Dialog is being shown.
I'm assuming that this is happening during the process of unpacking the installer? Running the installer with just a dummy file entry has the Welcome Dialog show up immediately.
In the [Files] section, I only specify a single relative folder:
Source: "{#Source}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Compression in the [Setup] section is set to:
Compression=lzma
SolidCompression=yes
Is there a dialog I can show during that time that gives the user visual feedback that something is being prepared?
To append to this question:
The last entry in the Log file before the 45 second hang is:
Extracting temporary file: C:\Users\Markus\AppData\Local\Temp\is-CBETM.tmp\license.rtf
I'm using a custom License Page on which I extract the file and load it as RTFText:
procedure LicensePage_Create;
var
LicenseFileName: string;
LicenseFilePath: string;
LicenseText: AnsiString;
begin
LicensePage := CreateOutputMsgMemoPage(wpSelectDir, SetupMessage(msgWizardLicense), SetupMessage(msgLicenseLabel), SetupMessage(msgLicenseLabel3), '');
LicensePage.RichEditViewer.Height := WizardForm.LicenseMemo.Height;
LicenseFileName := 'license.rtf';
ExtractTemporaryFile(LicenseFileName);
LicenseFilePath := ExpandConstant('{tmp}\license.rtf');
LoadStringFromFile(LicenseFilePath, LicenseText);
LicensePage.RichEditViewer.RTFText := LicenseText;
DeleteFile(LicenseFilePath);
LicensePage.OnActivate := #LicensePageActivate;
LicenseAcceptedRadio := CloneLicenseRadioButton(WizardForm.LicenseAcceptedRadio);
LicenseNotAcceptedRadio := CloneLicenseRadioButton(WizardForm.LicenseNotAcceptedRadio);
LicenseNotAcceptedRadio.Checked := True;
LicensePageID := LicensePage.ID;
end;
When you want to use SolidCompression (is it really worth it?), you have to put all files that are needed for the installer to start (like "license" file) before the big files.
Otherwise the installer has to decompress all the big files while starting.

Generate a configuration file with an entry for each selection using Inno Setup [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Based on what I pick in Inno Setup, the installer should add an entry containing package name followed by , into config.ini
And extract the right premade config files (that are stored in the installer) needed for the few specific setups into the Config folder.
There are plenty of programs like Chrome/Firefox which don't need any parameters or additional configs to install.
Desired config.ini file syntax:
<package1>, <package2 /X /Y /Z>, <package 3> ...
Etc.
Where <packageX> is a string value tied to the checkboxes in the installer selection menu.
After Inno Setup completes, it should run a batch file.
Bonus points: Again.. not only output the config.ini, BUT also extract necessary premade configs set-up for the specific program into a folder C:/NKsetup/Config/
Add each each of your packages as a component to the Components section. Then in the Files section, you can choose what files get installed based on the components selected. For the packages list config file, you need to code that with use of the WizardIsComponentSelected function.
[Setup]
DefaultDirName=C:\some\path
[Types]
Name: "custom"; Description: "-"; Flags: iscustom
[Components]
Name: "sqlserver"; Description: "Microsoft SQL server"
Name: "chrome"; Description: "Google Chrome"
Name: "firefox"; Description: "Mozilla Firefox"
[Files]
Source: "install.bat"; DestDir: "{app}"
Source: "common-config.ini"; DestDir: "{app}"
Source: "sqlserver-config.ini"; DestDir: "{app}"; Components: sqlserver
Source: "browsers-config.ini"; DestDir: "{app}"; Components: chrome firefox
[Run]
Filename: "{app}\install.bat"; StatusMsg: "Installing..."
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
ConfigPath: string;
Packages: string;
begin
if CurStep = ssPostInstall then
begin
if WizardIsComponentSelected('sqlserver') then
begin
Packages := Packages + ',sql-server-express /X /Y /Z';
end;
if WizardIsComponentSelected('chrome') then
begin
Packages := Packages + ',chrome';
end;
if WizardIsComponentSelected('firefox') then
begin
Packages := Packages + ',firefox';
end;
// Remove the leading comma
if Packages <> '' then
begin
Delete(Packages, 1, 1);
end;
ConfigPath := ExpandConstant('{app}\config.ini');
// This is not Unicode-safe
if not SaveStringToFile(ConfigPath, Packages, False) then
begin
Log(Format('Error saving packages to %s', [ConfigPath]));
end
else
begin
Log(Format('Packages saved to %s: %s', [ConfigPath, Packages]));
end;
end;
end;

Inno setup can not create desktop icon in windows 10

I have setup file for inno setup of latest version. It compiles and works great from windows xp to windows 8, but in windows 10 it fails on the moment when it creates desktop icon with next error:
IPersistFile::Save failed; code 0x80070002
This is how I create icon in setup file:
[Icons]
Name: "{userdesktop}\Forex Tester 4"; Filename: "{app}\ForexTester4.exe"; Tasks: desktopicon
Part of the installation log file:
2019-02-01 12:50:46.376 -- Icon entry --
2019-02-01 12:50:46.376 Dest filename: C:\Users\Mike\Desktop\Forex Tester 4.lnk
2019-02-01 12:50:46.376 Creating the icon.
2019-02-01 12:50:46.376 Exception message:
2019-02-01 12:50:46.376 Message box (OK):
IPersistFile::Save failed; code 0x80070002.
The system cannot find the file specified.
2019-02-01 12:50:59.066 User chose OK.
This folder exists and I can create files there manually. But inno setup fails to do this... All other icons except desktop one were created without problems.
Any ideas?
I had the same error on Windows 7 and Windows 10 because I was trying to create shortcut to file that didn't exist yet.
[Icons]
; Create icons for the app
Name: "{group}\{#AppName}"; \
Filename: "{app}\{#AppName}.lnk"; \
BeforeInstall: CreateAppRunLink();
Name: "{commondesktop}\{#AppName}"; \
Filename: "{app}\{#AppName}.lnk"; \
Tasks: desktopicon;
So I had to make sure that file "{app}{#AppName}.lnk" exists prior to creating the Icon:
This goes to [Code] section:
procedure CreateAppRunLink();
var
Filename: string;
Description: string;
ShortcutTo: string;
Parameters: string;
WorkingDir: string;
IconFilename: string;
begin
Filename := ExpandConstant('{app}\MyApp.lnk');
Description := 'Description';
ShortcutTo := 'Full path to file that will be run (MyApp.exe)';
Parameters := 'parameters if any';
WorkingDir := ExpandConstant('{app}');
IconFilename := ExpandConstant('{app}') + '\icon.ico';
CreateShellLink(Filename, Description, ShortcutTo, Parameters, WorkingDir,
IconFilename, 0, SW_HIDE);
end;
CreateAppRunLink will will be called after extracting any files from [Files] section which will make sure that our file is in place.
Hope that'll help.
It could be a relatively new (since version 1709) Windows 10 feature called Controlled folder access. See Allow a blocked app in Windows Security for instructions on turning it on or off.

inno setup to browse and extract zip file at sepcific location

I want to enable users to browse and extract zip files at a specific location.
Requirements/steps:
Display welcome page
Next display browse button to select installation directory(DisableDirPage=no)
Next display browse button to select zip file(JDK)
Extract JDK zip file selected in step 3 at location selected in step 2, that means JDK should be extracted in installation directory that user selects in step 2
Problems with my code:
After the first step my code directly jump into 3rd step and then it goes to 2nd.
The code to extract zip is not working if I pass method name as the parameter. If I pass the hardcoded value of the location it works. I don't know pascal and it basically seems to be a syntax related issue.
[SETUP]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
UninstallDisplayIcon={app}\MyProg.exe
DisableProgramGroupPage=no
DisableWelcomePage=no
DisableDirPage=no
Compression=lzma2
SolidCompression=yes
OutputDir=userdocs:Inno Setup Examples Output
[Files]
Source: "{code:GetLicensePath}"; DestDir: "{app}"; Flags: external
Source: "7za.exe"; DestDir: "D:\authorized\Builds\Solo\"; Flags: deleteafterinstall;
[Icons]
Name: "{group}\My Program"; Filename: "{app}\MyProg.exe"
[Run]
Filename: D:\authorized\Builds\Solo\7za.exe; Parameters: "x ""{{Code:GetZipPath}}"" -o""{app}\"" * -r -aoa"; Flags: runhidden runascurrentuser;
[Code]
var
Page: TInputFileWizardPage;
DataDir:String;
procedure InitializeWizard();
begin
Page :=
CreateInputFilePage(
wpWelcome,
'Select Zip File Location',
'Where is your Zip file located?',
'Select where Zip file is located, then click Next.');
Page.Add(
'Location of Zip file:',
'*.7z|*.rar|All files|*.*',
'.zip');
// Set initial value (optional)
Page.Values[0] := ExpandConstant('{%USERPROFILE}\Downloads\setup.7z');
;
end;
function GetZipPath(Param: string): string;
begin
DataDir := Page.Values[0];
end;
Could you help me, please?
The order of your custom page is determined by the first argument of the Create* function. So change wpWelcome to wpSelectDir.
Why double {{...}} - That’s likely the problem. Also code: should be lowercase.
Your scripted constant function does not really return anything. It should be:
Result := Page.Values[0];

Inno Setup: Asking for directory page if a task checked

Under the task section I have
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; \
GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "installFolder"; Description: "Install project folder."; \
GroupDescription:" folder";
and in the Files section is this particular folder
Source: "C:\\Output\LEA\*.*"; DestDir: {code:GetDataDir}; \
Flags: createallsubdirs recursesubdirs ignoreversion;
My aim is to test the for the checked button and then have a window to ask for the directory to install the folder to.
if WizardForm.TasksList.Checked[3] then
GetDataDir;
Can this be done without the need to create pages or the one page to get the directory?
Also, is this a good way to handle extra files that are optional and will be installed to a different location than the default {app} location?
The confusing part for me thus far is when it's all compiled, the GetDataDir is being called before the page to select Tasks. So I choose my directory and then I'm asked whether I want to install it or not. I don't know how to go about getting the GetDataDir to occur afterwards.
The wizard model in Inno Setup means you should always create the wizard pages, but you can skip the ones that don't need to be shown.
This can be done in the ShouldSkipPage() event function by calling IsTaskSelected():
function ShouldSkipPage(PageID: Integer): Boolean;
begin
if (PageID = InstallFolderPage.ID) and not IsTaskSelected('installFolder') then
Result := True
else
Result := False
end;
In this case, with only a single check, it can be shortened to:
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := (PageID = InstallFolderPage.ID) and not IsTaskSelected('installFolder')
end;
As TLama said, you don't need to do anything special in the {code:...} functions, just return the appropriate value directly.
You simply need to add '; Tasks: installFolder' at the end of your Source... line, then it won't be called unless the task as been selected.
Source: "C:\\Output\LEA\*.*"; DestDir: {code:GetDataDir}; Flags: createallsubdirs recursesubdirs ignoreversion; Tasks: installFolder

Resources