Create INI file if not exist and write a value - inno-setup

I copy an INI-file from {src} to {app} during the installation with use of the external flag, then I add a key to that file.
If the file does not exist in {src}, it should be created (then a key should be added) in the {app}.
Is it possible to "Create if not exist" inside the [Files] or [INI] or I definitely have to do it in the code-section?

[INI] section automatically creates the INI file, if it does not exist yet. So you have no problem there.
For [Files] section, see
Install only if external file exists.
So in the end, your script should be as simple as:
[Files]
Source: "{src}\MyProg.ini"; DestDir: "{app}"; \
flags: external skipifsourcedoesntexist
[INI]
Filename: "{app}\MyProg.ini"; Section: "Section"; Key: "Key"; String: "Value"

Related

Read destination directory from ini file during install time in Inno Setup

I need to read a directory path from an ini file at install time.
Under the [Code] section I have defined a function like
function GetDirectoryFromIni: String;
begin
Result :=
GetIniString('Directories' , 'Name' ,
ExpandConstant('{app}')+'\Default_Path\' ,
ExpandConstant('{app}')+'my_ini_file.ini');
end;
How can I use this function/path/string in the [Files] section?
Something like:
[Files]
Source: "C:\Source_Directory\*.*"; DestDir: "GetDirectoryFromIni"; \
Flags: ignoreversion
The basic logic is if the user has changed the "Default_Path" from a previous installation I want to adjust to use it, otherwise it uses the default path when the program is first installed.
I cannot seem to define or set a string variable to use the GetDirectoryFromIni result. Can anyone help?
You can do this even without any Pascal Script code. There's {ini} "constant":
[Files]
Source: "C:\Source_Directory\*.*"; \
DestDir: "{ini:{app}\my_ini_file.ini,Directories,Name|{app}\Default_Path\}"; \
Flags: ignoreversion
For an answer for your expected solution, see:
Using global string script variable in Run or other section in Inno Setup
You need to refer to the function in the [Files] section like
[Files]
Source: "C:\Source_Directory\*.*"; DestDir: "{code:GetDirectoryFromIni}"; Flags: ignoreversion
Then it works.

How to get current setup directory for the script section?

Under the [Run] section I want to change the working directory to the directory from which the installer was executed. For example, if the setup was executed from the Desktop, I want the working directory to point to the Desktop:
Filename: "{app}\setup.exe"; WorkingDir: "{app}"; MinVersion: 0.0,6.0; Flags: skipifsilent
Use the {src} constant. The documentation describes it as:
{src}
The directory in which the Setup files are located. For example: If
you used {src}\MYPROG.EXE on an entry and the user is installing from
"S:\", Setup will translate it to "S:\MYPROG.EXE".
In your case you can use it like:
[Run]
Filename: "{app}\setup.exe"; WorkingDir: "{src}"; MinVersion: 0.0,6.0; Flags: skipifsilent

Inno Setup can't handle Source path with space

my application has this directory that I need to include in the install package:
bin\Win Files\*
So, in the [Files] section, I have this line:
Source: "bin\Win Files\*"; DestDir: "{app}\bin\Win Files"; Flags: ignoreversion; Permissions: everyone-modify
But at compile time, it keeps saying it can't find that directory due to space in the path, the exact error message is:
No files found matching "C:\dev\packages\MyApp\bin\Win Files\*"
I've tried the following, all failed:
Source: """bin\Win Files\*"""
Source: "\"bin\Win Files\*\""
Source: '"bin\Win Files\*"'
That directory has to be named like that, so what should I do?
I use this:
[Files]
; Main application
Source: "{#SourceDir}\*"; DestDir: "{app}\"; Flags: recursesubdirs ignoreversion;
to copy all my files in one go to the installer. Note the recursesubdirs flag. I think spaces in the path (referenced here in the variable named SourceDir) are not actually a problem here.
This is due to the misunderstanding about the directory/file structure scanning mechanism in Inno Setup.
First of all, as #Martin Prikryl pointed out, one can include path that has space in it.
I think the following two rules are the key to this issue:
One cannot specify a folder that has no standalone files (e.g. empty folder or a folder that only has sub-directories). In my case: I have the following file structure per this question:
bin\Win Files\Libs\
bin\Win Files\Plugins\
So Source: "bin\Win Files\*"; will fail. If there is at least one standalone file under the "bin\Win Files\" folder, then the source line will work.
Inno Setup requires each folder be explicitly specified in the [Files] section as below:
Source: "bin\Win Files\Libs\*"; DestDir: "{app}\bin\Win Files\Libs";
Flags: ignoreversion; Permissions: everyone-modify
Source: "bin\Win Files\Plugins\*"; DestDir: "{app}\bin\Win Files\Plugins";
Flags: ignoreversion; Permissions: everyone-modify
as Source: "bin\Win Files\*"; will NOT include the sub-directories automatically, it is only used to include the standalone files under the bin\Win Files\ folder.

Installing file in users AppData folder using inno-setup

I am using Inno-Setup version 5.5.3(a).
[Files]
Source: "C:\GPT\GPT.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\GPT\GPT.dat"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
I would like to install the "GPT.dat" file into the users AppData folder in a custom folder called "GPT"
e.g. AppData\GPT\
for example, in my delphi code, I create a folder called "GPT" in the users AppData path. These is where I would like to place the file
var
path: array[0..MAX_PATH] of char;
SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, #path);
userPath:= Path;
UserPath:= UserPath + '\GPT\';
if not DirectoryExists(UserPath) then
CreateDir(UserPath);
Can anyone tell me how to edit my [Files] section of my Inno script to make this happen?
Thanks
You need to use the {userappdata} constant, which is mapped just to the CSIDL_APPDATA item ID, as a destination directory for your files:
[Files]
Source: "C:\GPT\GPT.dat"; DestDir: "{userappdata}\GPT\"; Flags: ignoreversion createallsubdirs recursesubdirs comparetimestamp
{userappdata} & {commonappdata}
The path to the Application Data folder.
CSIDL_APPDATA = {userappdata} = C:\Documents and Settings\username\Application Data
CSIDL_COMMON_APPDATA = {commonappdata} = C:\Documents and Settings\All Users\Application Data
You need to use : {userappdata}
If you check the Inno Setup documentation :
{userappdata} = C:\Documents and Settings\username\AppData\Roaming\
{commonappdata} = C:\Documents and Settings\All Users\AppData\Roaming\
{localappdata} : The path to the local (nonroaming) Application Data folder.
{userappdata} & {commonappdata} : The path to the Application Data folder.
I use :
[Files]
Source: MyPath\* ; Flags: recursesubdirs createallsubdirs; DestDir: {userappdata}\MySoftware\ ; Components: ConfigFiles
And my config files are in :
C:\Users*\AppData\Roaming\MySoftware**
It seems more appropriate to use {programdata}, if I interpret Mirals comment correctly.
However, on XP there is no {programdata}, only {commonappdata} or {userappdata}, so I have to diversify my install. {programdata} is a later invention.
A disturbing trap is when the desktop and userappdata are mirrored to the server ("roaming profile"), that slows programs down greatly if they use userappdata for ini file storage, at least that's my experience.

Make folder hidden after Inno Setup installs it

My application has a folder of files that are all marked as "hidden" (including the folder itself). However, Inno Setup won't copy them for installation unless I remove the "hidden" attribute first.
Fair enough, but is there a way to make Inno Setup mark the installed folder as "hidden" after it finishes setup on my end-user's machine?
Thanks.
See the Attribs parameter for entries in the [Dirs] section.
[Dirs]
Name: "{app}\blah"; Attribs: hidden;
Note that this won't really stop people from seeing it, just make it look like you have something to hide.
First of all, ensure that ONLY the directory is hidden, and not the subdirectory. Say its name is srcHiddenDir.
Now, create another directory dstHiddenDir, but dont make it hidden now. But it should be empty.
Then, open the settings.json, and replace all the occurrences of srcHiddenDir with dstHiddenDir.
Now, Make it ready to copy files as usual. In one part of the code, you will get:
[Files]
Source: "wherethewholecodeis\phpdesktop\phpdesktop-chrome.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "wherethewholecodeis\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "wherethewholecodeis\*srcHiddenDir*\*"; DestDir: "{app}\*dstHiddenDir*"; Attribs:hidden; Flags: ignoreversion recursesubdirs createallsubdirs
Then, you need to write:
[Dirs]
Name: {app}\dstHiddenDir; Attribs:hidden;
Name: {app}\dstHiddenDir\application; Attribs:hidden;
Name: {app}\dstHiddenDir\database; Attribs:hidden;
Name: {app}\dstHiddenDir\css; Attribs:hidden;
....
...and all the subdirectories you want to hide, just for more safety. But Note those subdirectories should be genuine, and there in the source/destination. Else, when you run the setup, error will show that these directories dont exist.
Now, compile the program.
Hope this helps.

Resources