ClickOnce
ClickOnce deployments will simplify your deployment a lot. To deploy your application, all you need to do is:
- specify the location to publish the application (i.e. a network drive, web site or ftp),
- specify from what location the users will install it from (propably the same as 1), and
- decide whether the application should be installed at the start menu, or always must be started from the install path (2).
Now, for you to deploy a new version, all you do is click "Publish". When the user then starts the program, the update will be found and installed (if permitted by the user). Very easy!
Application Path
ClickOnce deployment doesn't come for free though. First of, the application won't be installed under "C:\Program Files\MyCompany\MySoftware" as you might expect, but at some secret place (hidden from the user and developer). If you decide to let the installer add a shortcut to your start menu, there is no way to find out where this shortcut points, as it's not a normal shortcut. Right clicking on it and selecting properties will not give you the information you expect, i.e. the path to the executable.
Now, there is a simple way of finding out the path of the executable. When starting the installed application, the property Application.ExecutablePath will be correctly set and you can thus be used to, for example, add to the PATH environment variable:
void UpgradePathVariable()
{
string l_ApplicationFolder = Path.GetDirectoryName(Application.ExecutablePath);
string l_PathVariable = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine);
if (!l_PathVariable.Contains(l_ApplicationFolder))
{
l_PathVariable = l_OldPathVariable + ";" + l_ApplicationFolder;
}
Environment.SetEnvironmentVariable("PATH", l_PathVariable, EnvironmentVariableTarget.Machine);
}
Parameters
Also, because the program doesn't have a fixed installation path, there is no support for sending parameters to the program. I.e. args in static void Main(string[] args) will always be empty. The documentation at MSDN states that the only way to send parameters to a click once application is to deploy it at a web page, and let the user send html-parameters to it, i.e.:
http://www.yourdomain.com/yourapplication.exe?parameter1=val1¶meter2=val2
But
- this requires your application to be deployed using a web page, and
- you must always download the installer every time you need to sent parameters to the program.
pathtoyourexe "%1"
This would be both slow and hacky if using the recommended http-style mentioned above. Instead, by using the Application.ExecutablePath property, you can actually access the physical path to the installed executable, and thus add this path to the registry. With this setup correctly, right clicking on a file and selecting your program to open it with, will open the program and send the parameter correctly to it!
Settings
But, even though everything might seem to work out fine, you will soon notice that the Settings object defined in your application will be different if starting the program using the shortcut from your start menu, or right clicking on a file. They are not sharing the same application settings. And if you upgrade the program, all settings in your "right clicked version" will be gone, because the new version will be installed in a new folder.
In the end
Even though click once applications are really easy to deploy, and give you a lot for free, the limitations just makes them really hard to work with. Making simple applications might work, but as soon as you want the user to interact with it through the explorer shell, you are better off making your own installer (or using a free one such as NSIS). So in the end I decided to deploy my program manually using a source control, which made all my problems go away. Sending parameters worked, settings worked, and the application had a fixed folder!
The only thing I was really missing from ClickOnce was the ability for the program to automatically check for updates, which was something I really needed to make sure everyone using my application had the latest version (hopefully having less bugs in it). But it turned out this wasn't so hard to make on my own! The pseudo code for it, printed here, is divided in two programs - your main application, yourapp.exe, and the upgrade application, upgrade.exe.
yourapp.exe:
- Is there a new version available (i.e. check using source control)
- Copy upgrade.exe (and dependencies) to a new folder "temp"
- Start new process temp\upgrade.exe
- Close program
- Make sure all instances of yourapp.exe are closed
- Download the latest version (i.e. using source control)
- Start new process ..\
yourapp.exe - Close program
So, ClickOnce, good for small application, not good for more advanced applications.