Can I have more than one {app} variable in Inno Setup? - inno-setup

I am making an inno setup script. My setup really needs the user to choose to two customized install locations.
But there is only one {app} variable in inno.
Our software is an audio plugin software, the common way in this field is to choose one location for the program and the other location for audio sample/data (which is very large so users usually want to install at a dedicated place for storage and also performance purpose).
Is there any way to get around this condition?
Thanks a lot!

There are many other variables (Directory Constants) which you can use, most common ones:
{app} - The application directory (user chooses this derectory in Wizard dialog)
You can create subdirectories like {app}\Data
{win}
The system's Windows directory.
{sys}
The system's System32 directory.
{pf}
Program Files.
{cf}
Common Files.
And many, many others.
The modern installers store application in one directory - {app} and user's files in every user's custom directory - e.g. {localappdata}.
And if this is still not enough you can create your own dialog (wizard page) that contains edit boxes and Browse buttons for selecting directories.
Use function CreateInputDirPage() for this purpose.
See manual - Pascal Scripting: CreateInputDirPage for more info.

Take a look at the included CodeDlg.iss example that shows how to add an extra page for a data directory and hwo to use that value in [Code].

Related

Inno Setup - Constant for 'ProgramData' directory?

I want my setup program to copy some files into the Windows ProgramData directory, I see that most Windows directories have pre-defined constants already defined in the Inno Setup documentation, however I can't see one for ProgramData.
Therefore I am planning to use something like:
{sd}\ProgramData\MyCompany\MyApp
Is this the correct/best way to deploy to this directory using Inno Setup? It just seems odd to me that there is no constant for the ProgramData directory.
It's the {commonappdata} constant.
It's named so, because historically (Windows XP) the path used to be C:\Documents and Settings\All Users\Application Data (now that's a symbolic link to the C:\ProgramData).
And for the same reason, using the {sd}\ProgramData is not the correct way.

Inno Setup: Associating a range of file extensions

Is there a way in Inno setup to register a range of file extensions with a program?
What I want to do is set up a file associations page and ask the user if he wants to associate files with the extension n1..n99 with my program.
I can see how the tasks page works with individual file types, but I want to register 100 file extensions in one go. As it stands this would put 100 check boxes on the Associate files page.
Can this be done with pascal script, anybody got any ideas on how to do it?

InnoSetup's ignoreversion flag: For which file types?

InnoSetup has the ignoreversion flag for items in the [Files] section to specify that the file should be copied regardless of its version information. This is kind of the default that I would expect from a setup most of the time, yet it is not the default behaviour if it is not set. So I see this flag set in most setups for every file item, executables and non-executables alike.
I'm wondering what the file types are for which this flag makes any difference? Obviously .exe and .dll are affected, and .txt is not. Is there some definitive guide on this? I'd like to get rid of these extra flags on my file items if they serve no purpose.
The general recommendation I always give is to absolutely always use ignoreversion on every file in {app}.
It causes no harm on files without resources (and potentially improves performance in that Inno doesn't have to waste time discovering that they lack resources), and is almost always what you want for app files (otherwise you can end up in some weird frankenstate with a mixture of files).
However for files installed outside of {app} (typically either {sys} or {cf}) you usually should not use ignoreversion and should instead only permit upgrades. But YMMV.
(Note that special care may need to be taken for ensuring upgrades of common files outside of {app}, as only EXE and DLL files typically have version information, and even some of those may lack it or it may not be updated consistently, depending on the source of the file. Other considerations also apply to common files, such as using sharedfile.)
(Promoted comment to answer.)
For which file types is the "ignoreversion" flag meaningful ?
For those that can have Windows resources. Version information reading in Inno Setup falls deep down to Windows API so it's actually the system which determines from which files the version information can be read. Currently, the About Version Information topic specifies the files, that can have version information briefly as:
You can add version information to any files that can have Windows
resources, such as DLLs, executable files, or .fon font files.
Which narrows the list of possible files to the list of files that may contain resources. Unfortunately, there is no (and cannot be) a list of extensions of files, that might contain resources, because you can have a file with version information having some exotic file extension (I've asked for it a long time ago).
So, there is no credible advice, for which files you should keep or remove this flag.
Is the "ignoreversion" flag really intended ? When should I use it ?
More it makes me wonder, why to include the ignoreversion flag. I would say it should be used rarely and carefully only there, where you are sure a possible downgrade of a certain file won't hurt. Without it, the Inno Setup compares version of the installed file with an existing one and replaces it when it's older, which is in my view the most wanted behavior.
The version flags refer to the version of your application installer package and not to the DLL version of a file shipped with the installer. Because of this .txt files also have a version and the 'ignoreversion' flag makes sense for any file within the installer package. It's up to the developer to trace and adjust the file updates between application versions using any of the InnoSetup provided flags.

Determining standard file locations under Linux

Is there a standard way of determining file locations under Linux? Even better, are there any POSIX API's which allow the retrieval of standard file locations?
For example, how can I determine a user's home directory? Or, how can I determine the proper location for system configuration files?
I know that typically these locations would be "/home/username" or "/etc/". Should I just hardcode the paths as such?
The path to the current user's home directory is in the environment variable HOME. (I know systems where home dirs are spread over several partitions (say, /vol/vol[number]/[first letter]/[user name]) and not located in /home/.)
For other users, there's getpwent (and getpwent_r), which pull the home directory from the passwd entry.
For the other directories, there is the File System Hierarchy Standard, which most Linux distros adhere to and some other OSen as well.
I don't think there's an API for this. Thus, if a system does things differently, you're on your own -- good luck! ;-)
The current user's home directory can be found in the HOME environment variable. For other users, you can use the getpwnam or getpwuid functions (or the _r variants) to look up another specified user's home directory, among other things.
I know that you didn't ask this, however if you're looking to find the location of an executable, you can use which

linux script, standard directory locations

I am trying to write a bash script to do a task, I have done pretty well so far, and have it working to an extent, but I want to set it up so it's distributable to other people, and will be opening it up as open source, so I want to start doing things the "conventional" way. Unfortunately I'm not all that sure what the conventional way is.
Ideally I want a link to an in depth online resource that discusses this and surrounding topics in depth, but I'm having difficulty finding keywords that will locate this on google.
At the start of my script I set a bunch of global variables that store the names of the dirs that it will be accessing, this means that I can modify the dir's quickly, but this is programming shortcuts, not user shortcuts, I can't tell the users that they have to fiddle with this stuff. Also, I need for individual users' settings not to get wiped out on every upgrade.
Questions:
Name of settings folder: ~/.foo/ -- this is well and good, but how do I keep my working copy and my development copy separate? tweek the reference in the source of the dev version?
If my program needs to maintain and update library of data (gps tracklog data in this case) where should this directory be? the user will need to access some of this data, but it's mostly for internal use. I personally work in cygwin, and I like to keep this data on separate drive, so the path is wierd, I suspect many users could find this. for a default however I'm thinking ~/gpsdata/ -- would this be normal, or should I hard code a system that ask the user at first run where to put it, and stores this in the settings folder? whatever happens I'm going ot have to store the directory reference in a file in the settings folder.
The program needs a data "inbox" that is a folder that the user can dump files, then run the script to process these files. I was thinking ~/gpsdata/in/ ?? though there will always be an option to add a file or folder to the command line to use that as well (it processed files all locations listed, including the "inbox")
Where should the script its self go? it's already smart enough that it can create all of it's ancillary/settings files (once I figure out the "correct" directory) if run with "./foo --setup" I could shove it in /usr/bin/ or /bin or ~/.foo/bin (and add that to the path) what's normal?
I need to store login details for a web service that it will connect to (using curl -u if it matters) plan on including a setting whereby it asks for a username and password every execution, but it currently stores it plane text in a file in ~/.foo/ -- I know, this is not good. The webservice (osm.org) does support oauth, but I have no idea how to get curl to use it -- getting curl to speak to the service in the first place was a hack. Is there a simple way to do a really basic encryption on a file like this to deter idiots armed with notepad?
Sorry for the list of questions, I believe they are closely related enough for a single post. This is all stuff that stabbing at, but would like clarification/confirmation over.
Name of settings folder: ~/.foo/ -- this is well and good, but how do I keep my working copy and my development copy separate?
Have a default of ~/.foo, and an option (for example --config-directory) that you can use to override the default while developing.
If my program needs to maintain and update library of data (gps tracklog data in this case) where should this directory be?
If your script is running under a normal user account, this will have to be somewhere in the user's home directory; elsewhere, you'll have no write permissions. Perhaps ~/.foo/tracklog or something? Again, add a command line option, and also an option in the configuration file, to override this.
I'm not a fan of your ~/gpsdata default; I don't want my home directory cluttered with all sorts of directories that programs created without my consent. You see this happen on Windows a lot, and it's really annoying. (Saved games in My Documents? Get out of here!)
The program needs a data "inbox" that is a folder that the user can dump files, then run the script to process these files. I was thinking ~/gpsdata/in/ ?
As stated above, I'd prefer ~/.foo/inbox. Also with command-line option and configuration file option to change this.
But do you really need an inbox? If the user needs to run the script manually over some files, it might be better just to accept those file names on the command line. They could just be processed wherever, without having to move them to a "magic" location.
Where should the script its self go?
This is usually up to the packaging system of the particular OS you're running on. When installing from source, /usr/local/bin is a sensible default that won't interfere with package managers.
Is there a simple way to do a really basic encryption on a file like this to deter idiots armed with notepad?
Yes, there is. But it's better not to, because it creates a false sense of security. Without a master password or something, secure storage is not possible! Pidgin, for example, explicitly stores passwords in plain text, so that users won't make any false assumptions about their passwords being stored "securely". So it's best just to store them in plain text, complain if the file is world-readable, and add a clear note to the manual to warn the user what's going on.
Bottom line: don't try to reinvent the wheel. There have been thousands of scripts and programs that faced the same issues; most of them ended up adopting the same conventions, and for good reasons. Look at what they do, and mimic them instead of reinventing the wheel.
You can start with the Filesystem Hierarchy Standard. I'm not sure how well followed it is, but it does provide some guidance. In general, I try to use the following:
$HOME/.foo/ is used for user-specific settings - it is hidden
$PREFIX/etc/foo/ is for system-wide configuration
$PREFIX/foo/bin/ is for system-wide binaries
sym-links from $PREFIX/foo/bin are added to $PREFIX/bin/ for ease of use
$PREFIX/foo/var/ is where variable data would live - this is where your input spools and log files would live
$PREFIX should default to /opt/foo even though almost everyone seems to plop stuff in /usr/local by default (thanks GNU!). If someone wants to install the package in their home directory, then substitute $HOME for $PREFIX. At least that is my take on how this should all work.

Resources