Generic ClickOnce updates (With VSTO Support)
I use ClickOnce to publish all my applications I write internally, some of which are VSTO Outlook add-ins. The issue with the inbuilt ClickOnce updates is you have no control over it and it can slow start up time of your app.
So I wanted a generic class that I could put in my common library and use in any of my applications, VSTO or normal. This is what I came up with:
This is the public interface, under the covers most of the functionality is declared as protected virtual so functionality can be changed (which I use to create my VSTODeploy class).
Usage:
var deployment = new Deploy();
deployment.CheckForUpdateAsync(result => { if (result.Updated) { MessageBox.Show(result.Message, "Application Updated",
MessageBoxButton.OK,
MessageBoxImage.Information); } });
The base class is pretty simple and is just a nice wrapper for the ApplicationDeployment class. Where it gets tricky is updating VSTO applications, as the ApplicationDeployment.Update() method can corrupt your VSTO applications installation
Also because VSTO and .Net use a different security model, you will get exceptions as soon as you try to access the ApplicationDeployment information.
Kristopher Makey has a good solution to this problem and I used his solution and created my VSTODeploy class, which hides all the nasty implementation details, you can view his solution here: http://blogs.msdn.com/krimakey/archive/2008/04/18/click-once-forced-updates-in-vsto-ii-a-fuller-solution.aspx
There are two main points that he covers, fixing the Trust and make sure you use VSTOInstaller.exe to install your update otherwise you can break everything.
Here is my VSTODeploy class, I welcome feedback, I also have included an Extensions.cs class in the zip file below which you will need to compile this code.
The main extension method to note is StartProcess, it wraps Process.Start nicely making it easy to capture output from the exe as well as the return code.
public class VSTODeploy: Deploy
{
protected override UpdateResult UpdateApplication(ApplicationDeployment currentDeployment)
{
FixTrust(currentDeployment);
return base.UpdateApplication(currentDeployment);
}
protected override bool UpdateCurrentDeployment(ApplicationDeployment deployment, ref string message)
{
//Call VSTOInstaller Explicitely in "Silent Mode"
var installerArgs = string.Format(" /S /I {0}", deployment.UpdateLocation.AbsoluteUri);
var installerPath = Directory.Exists(@"C:\Program Files (x86)")
?
@"C:\Program Files (x86)\Common Files\microsoft shared\VSTO\9.0\VSTOInstaller.exe"
:
@"C:\Program Files\Common Files\microsoft shared\VSTO\9.0\VSTOInstaller.exe";
var vstoInstallerOutput = new StringBuilder();
var vstoStartInfo = new ProcessStartInfo(installerPath, installerArgs);
var returnCode = vstoStartInfo.StartProcess((sender, e) => vstoInstallerOutput.Append(e.Data));
message = vstoInstallerOutput.ToString();
return returnCode == 0;
}
private static void FixTrust(ApplicationDeployment currentDeployment)
{
//Create the appropriate Trust settings so the Application can do
//Click-Once Related updating
var deploymentFullName = currentDeployment.UpdatedApplicationFullName;
var appID = new ApplicationIdentity(deploymentFullName);
var everything = new PermissionSet(PermissionState.Unrestricted);
var trust = new ApplicationTrust(appID)
{
DefaultGrantSet = new PolicyStatement(everything),
IsApplicationTrustedToRun = true,
Persist = true
};
ApplicationSecurityManager.UserApplicationTrusts.Add(trust);
}
}
| Print article | This entry was posted by Jake Ginnivan on January 21, 2010 at 11:16 am, and is filed under Development. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |
about 1 month ago
This is a greate solution for resolving the differences between the 2 major ClickOnce paradigms.
One thing that you might want to consider updating in this code (a new post about this is forthcoming) is how you determine the path to VSTOInstaller. In VS2008, our primary focus was on getting all the pieces into place. As such we didn’t really have the full servicing story for VSTOInstaller worked out. It turns out that the next version of VSTO will be able to run both VSTO 4.0 and VSTO 3.0 customizations. As such, you may have seen the VS 2010 Beta and realized something: VSTOInstaller in the newest has moved. All is not lost, we’ve done a bit of work (albeit it’s still not perfect) about surfacing this: In the next version you will be able to check the following 32bit reg key:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VSTO Runtime Setup\v4]
“InstallerPath”=”C:\\Program Files\\Common Files\\Microsoft Shared\\VSTO\\10.0\\VSTOInstaller.exe”
For the path to the new VSTOInstaller. As you can tell, this is still a “version specific” key, so it’s possible in the “next next” version of VSTO, we’ll change things (hopefully for the better).
about 1 month ago
Interesting, thanks for the feedback. I will update the article to support v4 if installed, or fall back to v3 if it isn’t installed.
Appreciate your comments.
Jake