As promised, another post on actually writing code as I’ve been busy trying the help the p&p DocTools project out the door. One of the final hurdles was getting the VSTO Word Document Add-In use delay signing. I was missing a key step in this process…
- Build the binary using delayed signing
- Take the binary, finish signing them and put the fully signed version back in the bin\Release folder
- Regenerate the deployment and application manifests
- Build the setup project using the signed binary and the updated deployment and application manifests to build the final MSI.
It turns out that without step 3 you get errors like this after installing the MSI I would start Word for the first time or install the add-in using the deployment manifest then you see the following error as Add-In installed:
From: file:///C:/Program Files/Microsoft DocTools/Content Template/ppContent.vsto
File, Microsoft.Practices.DocxConverter.dll, has a different computed hash than specified in manifest.
************** Exception Text **************
System.Deployment.Application.InvalidDeploymentException: File, Microsoft.Practices.DocxConverter.dll, has a different computed hash than specified in manifest.
at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.DownloadAddIn(TimeSpan timeout)
Luckily I still have some contacts in the VSTO team and they quickly helped me out and told me about step three and, more importantly how to do it.
“The deployment manifest contains a reference to the application manifest (.manifest file), the application manifest hash value and the deployment manifest’s (.vsto file) hash to check for tampering. The application manifest contains the list of files in the solution (and their hash values) as well as its own hash value. So the reason you’re seeing that error is because the application manifest has a value for that assembly’s hash that is different from the assembly after it was delay signed.
So, after changing values in the application manifest (like the VSTA or VSTO sections in the manifest like “friendlyName” or “description”) or after modifying files listed in the application manifest (like delay signing), you need to update the application manifest, re-sign it, then update and re-sign the deployment manifest. The VSTO security model ensures that these files are signed and haven’t been tampered with (VSTO actually utilizes ClickOnce to do a lot of this checking).”
So error is caused by the hashes in the application manifest being out of sync with the actual hash value of my add-in binary. In turn fixing the application manifest will change its hash value so I’ll have to update the deployment manifest also.
How to fix it
There are several ways you can go about this depending on whether you want to do it manually, integrate it into a batch or fully automate it as part of an MSBuild script.
1) Using the MAGE UI
Run MAGE.EXE for a Visual Studio command prompt. From the menu select File|Open… and change the file filter in to “All Files” so that you can see the file types you need to edit. You will need to open both the application manifest (e.g. MyApp.dll.manifest) file and the associated deployment manifest (which is the MyApp.vsto file). The deployment manifest is located one level up from the application manifest in a published solution or is right next to the deployment manifest in a built solution.
Mage will then open two tabs (one for the application manifest and one for the deployment manifest). Select the application manifest tab (.manifest file) and click Save. If you get an error about entry points not existing, click Yes to continue. Then, when prompted to sign the manifest with a certificate, make sure that “Sign with certificate file” is selected and click the “…” button to browse for the certificate (.pfx file). VSTO 2008 projects automatically create a temporary certificate for your project that is located in your project folder. Mage will allow you to select any certificate you’d like but I’ll assume you’ll be using the temporary certificate. Therefore, browse to your project folder, select the PFX file and click OK. Now the application manifest is signed.
Next sign the deployment manifest, you first need to provide the path to the newly signed application manifest. Select the .vsto file tab, choose “Application Reference” and click “Select Manifest”. Browse to the application manifest you just re-signed and select it. Even if the path to the application manifest hasn’t changed you still need to do this. Click the save button and select a certificate like you did for the application manifest (above) and you’re done with the manifest updates.
2) Using MAGE via the command line
After updating the assembly that is delay signed, run the command to update the application manifest. You can also sign it at the same time.
MAGE –update [path to .manifest file] –certfile [path to PFX file]
Next, update and sign the deployment manifest.
MAGE –update [path to .vsto file] –appmanifest [relative path to .manifest file] –certfile [path to PFX file]
More details of the command line syntax can be found on MSDN’s MAGE.EXE documentation page.
3) Re-running the VSTO build target
I actually figured out this one by digging through the Microsoft.VisualStudio.OfficeTools.targets file in the Program Files\MSBuild folder. It turns out you can simply re-run the VisualStudioForApplicationsBuild target in the VSTO project after updating the binary. The following target will do this in your MSBuild project.
<PropertyGroup> <SourceDirectory>$(MSBuildProjectDirectory)\..\Source\</SourceDirectory> <Configuration>Release</Configuration> </PropertyGroup>
<ItemGroup> <VstoProjects Include="$(SourceDirectory)MyApp\MyApp.csproj" /> </ItemGroup>
<Target Name="RegenerateManifests" DependsOnTargets="SignBinaries"> <MSBuild Projects="@(VstoProjects)" Properties="Configuration=$(Configuration)" Targets="VisualStudioForApplicationsBuild" /> </Target>
The target RegenerateManifests runs after my SignBinaries target and calls the VSTO target to update the manifests.
Regardless of which option you choose, once this is done you should be able to build add-in and then your setup MSI and it’ll install correctly.
Props to Jeff and Viktor from the VSTO Team for helping me out on this one. You can also find more about VSTO Deployment on Paul Stubbs’ blog.