How to get path, where the InnoSetup script file you are currently compiling is located ?
To get script source path, use the preprocessor's predefined variable SourcePath. That variable you can expand in your script as an ordinary define. In case, the script was not yet been saved, it returns path to My Documents directory. Here's just a useless example to test:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
[Code]
procedure InitializeWizard;
begin
MsgBox(ExpandConstant('{#SourcePath}'), mbInformation, MB_OK);
end;
Don't forget that you have to compile the script (CTRL + F9) not only run (F9) to invoke preprocessor to rebuild the script.
Related
I have created files for a program I want to make as an update.
I would like it, before the installation, to check whether the program is also in the standard directory, and if not the one itself the right directory can choose where the program is.
I have tried this:
[Files]
Source: "C:\Data"; DestDir: "{app}"; Flags: ignoreversion
[Code]
function NextButtonClick(PageId: Integer): Boolean;
begin
Result := True;
if (PageId = wpSelectDir) and not FileExists(ExpandConstant('C:\Program\Test\Test.exe')) then begin
MsgBox('YourApp does not seem to be installed in that folder. Please select the correct folder.', mbError, MB_OK);
Result := False;
exit;
end;
end;
But during the installation it does not check it.
Whether the program is available or not, it installs it anyway.
I hope someone can help me.
You have to use the {app} constant in the test to check the selected folder:
FileExists(ExpandConstant('{app}\Test.exe'))
I am using Inno Setup to build my installer and I have the C:\Users\Public folder hardcoded in my [Files] section to place some files (Inno Setup does not have a constant for this folder)
My goal is to have the install create a C:\Users\Public\MyApp folder with some files in it. However when I run the install, it is creating the folder here:
C:\Users\Public\Public Documents\MyApp
Is this a permissions issue where the installer doesn't have access to create a folder directly under C:\Users\Public?
[Files]
Source: "MyApp\db.mdf"; DestDir: "{drive:{src}}\Users\Public\MyApp"; Flags: ignoreversion;
I cannot reproduce your problem. For me your code works. I've tested it on Windows Vista, 7 and 10. It always installs to C:\Users\Public\MyApp.
Though I do not understand the {drive:{src}}. How does the drive of the Users folder relate to the drive of the installer? You should use the {sd} constant:
[Files]
Source: "MyApp\db.mdf"; DestDir: "{sd}\Users\Public\MyApp"; Flags: ignoreversion
But anyway, to resolve the path to the C:\Users\Public, you can use the PUBLIC environment variable:
[Files]
Source: "MyApp\db.mdf"; DestDir: "{%PUBLIC}\MyApp"; Flags: ignoreversion
It works since Windows Vista.
Alternatively, you can use SHGetKnownFolderPath with FOLDERID_Public. For an example code, see Constant for AppData\LocalLow?
If you need to support even Windows XP, where there is no C:\Users\Public folder or PUBLIC variable, you have to find out, what path your need to use there instead (probably C:\Documents and Settings\All Users), and implement a fallback using a scripted constant:
[Files]
Source: "MyProg.exe"; DestDir: "{code:GetPublicPath}\MyApp"; Flags: ignoreversion
[Code]
function GetPublicPath(Param: string): string;
begin
Result := GetEnv('PUBLIC');
if Result <> '' then
begin
Log(Format('PUBLIC is "%s"', [Result]));
end
else
begin
Result := GetEnv('ALLUSERSPROFILE');
Log(Format('PUBLIC is not set, ALLUSERSPROFILE is "%s"', [Result]));
end;
end;
And for others, it's worth noting that your need for resolve C:\Users\Public is very specific, related to this question: C++ app MDB in ProgramData copies to user's AppData folder when I dont want it to.
One usually does not want the C:\Users\Public, but C:\Users\Public\Documents (= {commondocs}) or C:\ProgramData aka C:\Users\All Users (= {commonappdata}).
Is there a way to dynamically fill the [Dirs] and [Files] sections of an Inno Setup script?
Here is what I am trying to do:
during the install process, the user will select foo (foo matches a repository to get from our SCM)
Setup will run a batch to checkout foo from our SCM
then the content of foo must be added to the [Dirs] and [Files] sections of the script
Everything works fine except for the last step. I searched around and couldn't find explanations on how to do this. I have the feeling that my script should embed all the repositories of our SCM to then be able to copy only the selected ones to the destination directory.
Thanks for your help!
Regards,
See Inno Setup Prompt for external file location.
And add the recursesubdirs flag.
You may also need the createallsubdirs flag (assuming from your reference to the [Dirs] section).
[Files]
Source: "{code:GetScmPath}"; DestDir: "{app}"; \
Flags: external recursesubdirs createallsubdirs
[Code]
function GetScmPath(Param: string): string;
begin
Result := { make it return path to the checked out files }
end;
I want to have a checkbox at the finishpage of InnoSetup to open or not the readme file. I try something like this (like it's explain here flag postinstall but it seems doesn't works:
Name: "StartAfterInstall"; Description: Display the PDF Readme File; Languages: english
Filename: "{app}\readme.pdf"; Tasks: StartAfterInstall; Flags: shellexec postinstall runasoriginaluser; Languages: not French
It propose only to launch the program. Is there a way to do this without use the [code] section in Inno Setup or not?
For this task simply mark your readme file entry in your [Files] section with the isreadme flag and let the Inno Setup do the rest for you:
[Files]
Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme
The isreadme flag is described as (emphasized by me):
File is the "README" file. Only one file in an installation can have
this flag. When a file has this flag, the user will asked if he/she
would like to view the README file after the installation has
completed. If Yes is chosen, Setup will open the file, using the
default program for the file type. For this reason, the README file
should always end with an extension like .txt, .wri, or .doc.
Note that if Setup has to restart the user's computer (as a result of
installing a file with the flag restartreplace or if the AlwaysRestart
[Setup] section directive is yes), the user will not be given an
option to view the README file.
I'm using an Inno Setup script to install my 32- and 64-bit DLLs in a 64-bit install. I can get the 64-bit path from a registry setting, but the 32-bit path is missing does not exist. However, I know that the path's 'tail' is constant, just the head needs to be modified. Ie,
64-bit (from registry) = c:\Program Files\My Application\Bin
32-bit (derived) = c:\Program Files (x86)\My Application\Bin
So what I do is swap out the 64-bit program file path with the 32-bit one. I do this easily with StringChangeEx:
RegQueryStringValue(HKLM, 'SOFTWARE\My Application', 'RootDir', sPath)
if IsWin64() then
StringChangeEx(sPath, ExpandConstant('{pf}'), ExpandConstant('{pf32}'), False);
sPath is returned with my 32-bit path. This works great on most systems, but it seems that sometimes StringChangeEx does not swap out 'C:\Program Files' for 'C:\Program Files (x86)'. I have verified (using MsgBox's) that the {pf} and {pf32} constants are what I think they are. Casing is the same and there are no leading/trailing spaces. It just seems that on some systems, the function doesn't work.
I'm using the latest version of InnoSetup (10/2010). The web site doesn't mention any problems with this function. Has anyone else seen this and/or have any ideas on what it could be?
I threw together this little script and using 5.4.0 (10/2010 release), it worked:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
[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={{AE1A6BBB-7582-43AA-85F5-C7F984D1A68B}
AppName=My Program
AppVersion=1.5
;AppVerName=My Program 1.5
AppPublisher=My Company, Inc.
AppPublisherURL=http://www.example.com/
AppSupportURL=http://www.example.com/
AppUpdatesURL=http://www.example.com/
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
[Code]
function InitializeSetup(): Boolean;
var
sPath : string;
begin
sPath := ExpandConstant('{pf}') + '\mypath';
if IsWin64() then
StringChangeEx(sPath, ExpandConstant('{pf}'), ExpandConstant('{pf32}'), False);
MsgBox(sPath, mbInformation, MB_OK);
result := true;
end;
Does my script work or fail for you?
Is sPath correct before your call to StringChangeEx?
I would suggest the /LOG option but code isn't logged automatically. You would need to add Log(const S: String) calls.
Turns out that the registry entry sometimes had a lower-case drive letter. I changed the code to:
RegQueryStringValue(HKLM, 'SOFTWARE\My Application', 'RootDir', sPath)
sPath := Lowercase(sPath);
if IsWin64() then
StringChangeEx(sPath, Lowercase(ExpandConstant('{pf}')), Lowercase(ExpandConstant('{pf32}')), False)
I had assumed the registry entry was not the problem, but not quite so.