Thursday, April 29, 2004

I'm working in VS.Net, and I'm creating a setup package. I ran into an obscure problem that I just had to pass along. When you create a setup package, an MSI file, it doesn't include the ability to create any procedure based code like the old, really lousy setup funtionality under the old Visual Studio.

When you register users, you sometimes want to create a file, in my case an XML file containing configuration information, in the folder the user selects for the installed application. The problem is, you can't use "Application.StartupPath" in an EXE that is called from the MSI file, because that file runs in a temp folder, and there is no point in creating a settings file there. Obviously, you want to save the file to the folder where the application is running, but how do you pass the user's selection to your registration EXE at runtime?

The setup package offers a screen named "Installation Folder", which is where the user selects the deployment folder. You can get at the string the user selects using the attribute "TARGETDIR", however there is a trick to it, and that's what I wanted to pass along.

In your "Register User" screen, the one that calls your registration EXE, you have an attribute called Arguments. To correctly pass the path to your EXE, you have to make sure it can accept command line arguments, and example of which you can find here.

To put it short, the text you should enter in the arguments field is (in bold for clarity) "[TARGETDIR] . Notice the quotation mark at the beginning and not the end of the string. Isn't that nasty? If you don't add this, you are going to end up with an arguments array that automatically splits at any space characters, (" "), so if you try to read the value your going to get "C:\Program" because of the space in "Program Folders". If you add the quotation mark at the end, like "[TARGETDIR]", you end up with a path that includes a trailing quotation mark, such as C:\Program Files\Company\Application" . Another option would be to join the elements in the array within your EXE, but this is just easier, and gives you the ability to pass arguments as well, although I haven't teased out the syntax for this.