Inno Setup creating an unwanted empty folder with value in DefaultDirName - installation

Inno Setup installer is creating an unwanted empty folder using my initial value of DefaultDirName, even though I have set WizardForm.DirEdit.Text = 'c:\preferredinstalldir' in CurStepChanged (curStep = ssInstall). The installer puts the files in the right installation folder, but because I have to assign a dummy value to DefaultDirName, it creates that dummy folder. I have tried using a {code:xx} function for the DefaultDirName but since the actually folder I want hasn't been determined until the wizard runs, I seem to need a placeholder folder (but I don't want it created!)
AppId = {code:GetAppId}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppCopyright={#MyAppCopyright}
VersionInfoCopyright={#MyAppCopyright}
AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetFilesDestDir} //this says error path not valid, no root/unc etc etc because the function has no path set yet
DefaultDirName=c:\mydummyfolder //this creates a dummy folder even though the files are installed correctly to location i set later in CurStepChanged (I assign WizardForm.DirEdit.Text := InstallPath )
DisableDirPage=yes
DefaultGroupName=SomeName
DisableProgramGroupPage=yes
OutputBaseFilename=mysetup_setup
Compression=lzma
SolidCompression=yes
UsePreviousAppDir=no
UsePreviousLanguage=no
UninstallFilesDir = {code:GetFilesDestDir}\uninst
.............
function GetFilesDestDir(def:string): string;
begin
if InstallPathSet then
begin
Result := InstallPath;
end
end;
I've seen this question here
Inno Script: Strange Empty Folder
but it wasn't answered and I couldn't post a comment.

I think I've found the solution, setting CreateAppDir=no seems to do the trick.At least its no longer creating an empty folder at the initial dummy location.

I cannot reproduce what you describe.
Changing WizardForm.DirEdit.Text in CurStepChanged(ssInstall) has no effect at all. It's too late.
Anyway, just change the value sooner. For example in the InitializeWizard or CurPageChanged.

Related

How to test if a folder can be deleted

I am writing a Lua function to delete a folder using Luacom in Windows (version 7 onwards and I can't dictate the version). The folder path is specified in UTF-8 and will contain non-ASCII characters, so os.remove, io.whatever, Penlight and lfs will not work. So far I have (using Luacom to access the Windows com model):
function delFolder(sPath, bForce)
--sPath is a fully specified folder path
--bForce is a Boolean indicating whether the folder should be
--deleted even if it contains read-only files
require('luacom')
fso = luacom.CreateObject("Scripting.FileSystemObject")
--code in here to test that the folder exists,
--and return an error if it does not
fso:DeleteFolder(sPath, bForce)
end
My problem is that, if bForce = false, and the folder is effectively read-only, the operation errors out. I need to be able to test for this situation and return an error instead of attempting the operation.
One possibility is to manipulate the Luacom error handling not to abort on error, and test the last error after the operation:
luacom.config.abort_on_error = false
luacom.config.last_error = nil
fso:DeleteFolder(sPath, bForce)
if luacom.config.last_error then
--return error indicating that the folder cannot be deleted
end
but is there a simpler way, using the com model or some other alternative available in Lua?
Reference for FileSystemObject

How to use the {app} path name in Inno Setup UninstalledAll message?

I see how to use the macro [name] or [ver] in a message in Inno Setup. Is there any way to use the application path (specified elsewhere in Inno Setup by {app})? When I uninstall my app, I want to tell the user that a file still exists on the disk with the pathname of the app and that there's an environmental variable that contains it. I don't want to delete the file with the pathname and I don't want to clear the variable, because they might have other paths in them, but I do want to warn the user.
This is the Inno Setup entry I'm trying to fix:
[Messages]
UninstalledAll=%1 uninstall complete.%n%nI did not try to remove the APP-PATHNAME-HERE from the PATH16 environment variable, or from the PATH statement in autoexec.bat in your otvdm\C folder. You may safely ignore these.
That's not a custom message. That's a standard message. You cannot modify standard messages this way.
All you can do is to display yet another message. For example from CurUninstallStepChanged(usPostUninstall).
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
Message: string;
begin
if CurUninstallStep = usPostUninstall then
begin
Message :=
Format('I did not try to remove the %s from the PATH16 environment variable, ' +
'or from the PATH statement in autoexec.bat in your otvdm\C folder. ' +
'You may safely ignore these.', [ExpandConstant('{app}')]);
MsgBox(Message, mbInformation, MB_OK);
end;
end;

Inno Setup - Create folder in Public Users Documents in Windows 10

I am trying to add a folder to an installation which will eventually hold user output data. I can't put a folder into Program Files because users will not have the required permissions to write to it.
If it is not being installed to Program Files, then the data folder can be created inside the application folder (this is working fine).
I have a little piece of code to detect whether the installation was made to Program Files and, if so, I wanted to use CreateDir() to make a data folder in C:\Users\Public\Documents\{'MyAppName}\DB This seems to fail, in [Code] even though the standard Inno Setup script works:
[Dirs]
Name: "{commondocs}\{#MyAppName}\DB"
I am using the DeinitialiseSetup() procedure to make this happen at the end of installation, once the path is definite.
This is my code:
[Code]
procedure DeinitializeSetup();
begin
{ If it has been installed in the Program Files Folder put DB in Public Documents }
if Pos(ExpandConstant('{pf}'),ExpandConstant('{app}')) > 0 then
begin
if not CreateDir (ExpandConstant('{commondocs}\{#MyAppName}\DB')) then
MsgBox('Error: Data folder could not be created.', mbInformation, MB_OK);
end
else
begin
if not CreateDir (ExpandConstant('{app}\DB')) then
MsgBox('Error: Data folder could not be created.', mbCriticalError, MB_OK);
end;
end;
Following another SO suggestion I used:
PrivilegesRequired=lowest
in the script but it did not work with or without this. I am beginning to think this may be a permissions issue but am not sure why, as the installer standard [Dirs] script works fine.
This is not the same as the other questions regarding identifying the path - I have got all the paths I want, only: [Code] CreateDir() does not seem able to create a folder in {commondocs}.
Many thanks for any suggestions.
My guess is that the {commondocs}\{#MyAppName} does not exist. CreateDir function can create a single directory only. It won't create parent folders for you, if they do not exist (contrary to [Dirs] section entry).
You can use ForceDirectories function instead:
Creates all the directories along the specified directory path all at once.
Side note: Do not use DeinitializeSetup to create the directories – Is is triggered even if the installation fails, or even if the user cancels the installation.
Use CurStepChanged(ssPostInstall):
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
{ Your code }
end;
end;

Permanent customized folder icons with InnoSetup in any computer

I have modified some folder icons and I am including these folders in my InnoSetup installation. The problem is that once my program is installed, my customized folder icons are gone and what I see is just the oldfashioned "yellow" Windows folder icons.
EDIT
The answer was provided by the user TLama. It worked in my computer at first. I had some problems with different Windows versions at different computers. I will write now my working code after having tried sucessfully in several computer systems.
Icons used:
Ico1.ico
Ico2.ico
Ico3.ico
Modified folder icons:
c:\FDR1
c:\FDR2\FDR3
Step 1:
I have used the software "Folder icon changer" to have my icon in place for the three folders I wanted changed. You may use any other free software too. After execution, a desktop.ini appeared in each of the newly changed icon folders. For instance, the FDR1 has the content:
[.Shellclassinfo]
Iconfile=F:\Resource\Icons\Ico1.ico
Iconindex= 0
Step 2:
I have then erased the path above and saved "Ico1.ico" into the directory "c:\FDR1" I had just modified :
[.Shellclassinfo]
Iconfile=Ico1.ico
Iconindex= 0
I did the same for the Ico2.ico (inside the FDR2) and the Ico3.ico (inside the FDR3). The "Icon1, 2 and 3" and "desktop.ini" file attributes were all set to hidden. But, it is important NOT to set the icon properties to "read only".
Step 3:
Inside Inno repeat TLama's suggestion.
#define OutputDirectory_1 "c:\FDR1"
#define OutputDirectory_2 "c:\FDR2"
#define OutputDirectory_3 "c:\FDR2\FDR3"
[Dirs]
Name: {#OutputDirectory_1}; Attribs: system
Name: {#OutputDirectory_2}; Attribs: system
Name: {#OutputDirectory_3}; Attribs: system
[Files]
Source: "c:\FDR1\Ico1.ico"; DestDir: {#OutputDirectory_1}; Attribs: hidden system
Source: "c:\FDR2\Ico2.ico"; DestDir: {#OutputDirectory_2}; Attribs: hidden system
Source: "c:\FDR2\FDR3\Ico3.ico"; DestDir: {#OutputDirectory_3}; Attribs: hidden system
Step 4:
Compile !
Now, your folder icons will permanently work in any computer and system !!
Your target folder should have either read only or system attribute configured. To create such folder you can use, like Miral mentioned, [Dirs] section and its attributes. This will have an advantage, that after you run the installation process, InnoSetup automatically notifies Shell about changes, so the folder icon will be changed without an extra notification function call.
; this is a defined preprocessor variable used to simplify the script
; management; this variable contains the path, where the icon will be
; applied (it's used twice in a script, so it's easier to manage that
; from one place)
#define OutputDirectory "d:\TargetDirectory"
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=userdocs:Inno Setup Examples Output
[Files]
; here you need to use "hidden" and "system" values in Attribs parameter
; to include into the Desktop.ini file hidden and system file attributes
Source: "Desktop.ini"; DestDir: {#OutputDirectory}; Attribs: hidden system
[Dirs]
; here you need to use either "readonly" or "system" value in Attribs parameter
; to setup to the output directory read only or system file directory attribute
Name: {#OutputDirectory}; Attribs: readonly
Important:
Don't forget that you have to compile the script using CTRL + F9 before running, whenever you change the content of your input Desktop.ini file as well as when you change the value of the preprocessor path variable (I've been missing this few times and then wondering about the setup package content).
In order to activate custom folder icons you have to programmatically set the "read-only" attribute of the folder containing the desktop.ini file. (You can't do this from Explorer, but you can via the command line and from Inno.)
[Dirs]
Name: {app}; Attribs: readonly
Note that the path inside the desktop.ini file must be valid on the user's filesystem; you may want to use an [Ini] entry to create or modify this file to suit the installation path.
(This doesn't actually make the folder read-only -- this attribute is treated differently on folders by Windows because only files can meaningfully be read-only.)

Can i use FinalBuilder to set the name of a self extracting exe at Runtime?

When using FinalBuilder to package our website, I would like it to be able to set the filename when it creates the file set with a variable somewhere else. So the filename would be Website 1.4.exe
Has anyone got this working?
I'm new to FinalBuilder, so if you could give some more info it would be useful - like which action you're using to create the exe.
Have you tried using project variables? From what I've seen you can use them in most FB actions.
At worst you could use the rename file action:
create a new project variable ([Tools\Edit Variables\Add]) called Version and give it a default value
if you need to, you can add a Set Variable action to dynamically set the value of the variable
add a Rename action
set Rename File to the file you want to rename (including path) eg c:\Release.exe
set New Name to Release%Version%.exe
That if the Version project variable is set to 1.4, Release.exe will be renamed to Release1.4.exe

Resources