Application considerations


(Difference between revisions)
Jump to: navigation, search
(See also)
Current revision (12:45, 4 September 2009) (view source)
m (External links: C#, not C+)
Line 158: Line 158:
* Visual Basic: [ SplitPath] for Visual Basic on Tek Tips
* Visual Basic: [ SplitPath] for Visual Basic on Tek Tips
* Visual Basic: [ Locate the executable path] using Visual Basic
* Visual Basic: [ Locate the executable path] using Visual Basic
* Java/C#: [ SplitPath] for Java and C+ on the same page as a comparison
* Java/C#: [ SplitPath] for Java and C# on the same page as a comparison
Examples and discussions on how to set and retrieve an executable module's VERSIONINFO resource:
Examples and discussions on how to set and retrieve an executable module's VERSIONINFO resource:

Current revision



Windows application developers sometimes release their products without considering all effects afterwards. This can make it difficult, for instance, to provide updates, and the application may fail under certain circumstances. The purpose of this article is to cover some of the most common pitfalls.

Application working directory

On Windows there are many different ways of starting an application. Although most users may start the program via the Windows start menu, others may use a command line or an Explorer window. Therefore, the working directory may not always point to the folder where the application's executable resides.

If an application needs to read additional files from the start up folder, for example configuration files, direct link libraries (DLLs), etc, it will fail if the working directory points to somewhere else.

A user can set the working directory by altering the field 'Start in' in the shortcut's properties as shown in the picture on the right.

Inno Setup does not fill in this information automatically, hence an [Icons] section like

Name: "{group}\My Program"; Filename: "{app}\MYPROG.EXE"

would leave the 'Start in' field (the working directory) blank. Of course, Windows uses a default working directory, but this folder varies between different versions of Windows. That makes the start up folder somewhat random for developers.

If an application relies on that folder it will fail to find its configuration files or DLLs.

There is at least one way to fix this issue, one way to work it around, and one no-go.

The 'Path' environment variable could be changed to point to the application directory. This would solve the problem only for DLLs and executable files, hence that's the 'no go' (see Avoiding the Path environment variable), so don't do that.

The [Icons] section entry of the Inno Setup script can be altered so that a 'Workingdir:' parameter is specified. That's the workaround.

Name: "{group}\My Program"; Filename: "{app}\MYPROG.EXE"; WorkingDir: "{app}"

This does not help much if the user starts MYPROG.EXE from a command line window which has a working directory pointing to somewhere else. To finally fix this issue and make it work in all cases the application itself needs to be changed unless the program is meant to run with different configuration files/DLLs from different working directories.

The Windows API GetModuleFileName () can be used to retrieve the application's executable module file path before any configuration files or DLLs are loaded. Developers can then separate the folder information from the executable's file name and use this directory whenever a configuration file or a DLL is to be loaded, or even change the current directory immediately.

Here's a quick example in C, but better use _splitpath or _wsplitpath. For improvements have a look at Security Development Lifecycle (SDL) Banned Function Calls as well.

char chAppPath [1000];
char *chBackSlash;

if (GetModuleFileName (NULL, chAppPath, 1000 - 1))
    chBackSlash = strrchr (chAppPath, '\\');
    if (chBackSlash)
        if (strlen (chAppPath) > 2)
            *(chBackSlash + 1) = '\0';
        SetCurrentDirectory (chAppPath);

Examples for splitting up the path retrieved by GetModuleFileName () or similar functions in different programming languages:

Some languages, mostly interpreters, provide macros or constants for the executable or script directory. AutoIt, for example, provides the macro @ScriptDir. Inno Setup itself provides the constant {src} for the folder in which the setup.exe resides.

Application versioning

There will almost certainly be a day in the future where an application needs to be updated.

Every new version will probably have its own installation program created with Inno Setup or any other setup generator. A user could try install an older version over a more recent one.

How can the setup program determine whether the installed version is more recent than the installation package or whether it needs to be replaced?

A date/time stamp is not a very good indicator as it can easily be changed by the user or other circumstances.

Windows provides a VERSIONINFO resource for that case. Applications that contain a correct version info resource are automatically handled by Inno Setup and other installers. The resource can be accessed on the 'Version' page of the 'Properties' dialog window (picture on the right).
Source: "MYPROG.EXE"; DestDir: "{app}"

Inno Setup can also ignore the version info but that would spoil the whole idea of version management:

Source: "MYPROG.EXE"; DestDir: "{app}"; Flags: ignoreversion

The VERSIONINFO has to get into the program somehow. Here are some links for different languages:

Application is running

When trying to apply an update or to reinstall the application the user could have the program running. Because running executable modules are normally locked by the operating system (there are exceptions, but they are negligible) the installer can't replace it, hence the update, reinstallation, or removal, fails.

Windows provides a whole bunch of options to check whether an application is running. The article Detect if an application is running discusses some of them.

For GUI programs that require user interactions a mutex object seems to be the most reliable and least intruding method. Mutexes can be used for many things but in this case Inno Setup can detect an existing mutex which will indicate that the application is currently running.

By default Inno Setup supports application mutexes by asking the user to close the program first before applying the update, the reinstallation, or uninstallation. See [Setup] AppMutex= in Inno Setup's help file online.


Inno Setup can only detect a mutex (ie. a running application) if the program has created one. This should take place right at the start of the program. The mutex object is automatically destroyed upon application termination. The operating system takes care of the removal.

The text 'TheUniqueMutexNameForMyProgram' should be replaced by some unique name. The description for lpName of CreateMutex () provides more details on how to name a mutex object.

Because it takes only one Windows API call without significant overhead every GUI application should create a mutex on start up.

To create the mutex object in different programming languages the following examples can be used.


CreateMutex (NULL, FALSE, "TheUniqueMutexNameForMyProgram");


CreateMutex (nil, False, 'TheUniqueMutexNameForMyProgram');

Visual Basic (this code has been 'stolen' from Inno Setup's help file and was submitted by Peter Young):

'Place in Declarations section:
Private Declare Function CreateMutex Lib "kernel32" _
        Alias "CreateMutexA" _
       (ByVal lpMutexAttributes As Long, _
        ByVal bInitialOwner As Long, _
        ByVal lpName As String) As Long

'Place in startup code (Form_Load or Sub Main):
CreateMutex 0&, 0&, "TheUniqueMutexNameForMyProgram"

See also this Inno KB entry for information on how to detect when the application is still running from a different login than the one where the installer is being run.

See also

External links

Examples for splitting up the path retrieved by GetModuleFileName () or similiar functions in different programming languages:

Examples and discussions on how to set and retrieve an executable module's VERSIONINFO resource:

Personal tools