When you get a Software Publisher Certificate (SPC) from a third party CA (say Verisign) that is authorized by Microsoft to issue certificates, you actually get two files: a pvk and spc or cer file.
- .pvk file which contains the private key information.
- .spc or .cer file contains public key information.
In my discussion later, I'll consider having pvk and spc files for signing clickonce application.
To use this certificate, you need to generate a Personal Information Exchange file (pfx). You can generate a pfx file from pvk and spc. For detailed information on how to generate pfx file, follow here.
Visual Studio Support for Clickonce Manifest signing
Now I'll consider that you have a pfx file and you are ready to sign the clickonce manifest. To sign the clickonce manifest, open the properties window of the project and then select signing tab. Then select the “Sign the ClickOnce manifests” check box and you'll be prompted for selecting the pfx file. Open the pfx file and you'll be prompted for password. After putting your password, set the timestamp server URL to http://timestamp.verisign.com/scripts/timstamp.dll. The following figure shows the process in a whole.
Figure: Sign clickonce manifests.
Separate Signing from Development
You are done! But this is not why I'm writing this post. The problem is in this process that if you have automated build management system (say using NAnt) then during build you'll be prompted for password and you don't want this. You actually want to separate the signing from development. You only need to bother about signing when you deploy on production server. If put directly select pfx file from Visual Studio then every developer will be prompted for the password during build (at least once, then VS will cache it). So you need some way to sign the Clickonce manifest, say in post build event. But Publish doesn't have any event. So you can't write post build event in Visual Studio project. One way is to write batch script and run the script after production deployment build.
ClickOnce Manifest Internals
But before diving deep into the signing procedure, let’s discuss about how actually ClickOnce manifest works. If you publish your clickonce app in E:\Clickonce folder, then the root folder will contain a file named YOURAPPNAME.applicaiton. Then there will be a folder “Application Files\YOURAPPNAME_VERSION” and there’ll be several files.
Figure: ClickOnce Deployment Folder Structure
Clickone has two types of manifests: application manifest and deployment manifest. Deployment manifest has one of the three extensions:
- .application for executable application
- .vsto for office application
- .xbap for browser hosted WPF application
Application manifest has only one extension and that is .manifest.
Now if you want to manually sign clickonce manifest, then you need to sign both application and deployment manifests. Clickonce manifests contain hashes of all/related files. The following figure shows how application and deployment manifest share hash value.
Figure: Application and Deployment manifest hash value calculation.
Sign Application and Deployment Manifests
So if you sign clickonce manifest, then you need to sign the application manifest first as deployment manifest depends on application manifest file. So let's start with the signing process:
- Sign the application manifest:
If your application manifest has a .manifest extension and you'll get the application manifest file in “Application Files\Application_VERSION” folder. The following command signs a manifest file with pfx.
mage -update MyApplicaiton.exe.manifest
-certfile pfxfile.pfx -Password pfxfilepassword
mage command will be available if you have a .NET SDK installed.
- Sign the deployment manifest:
mage -update MyAppName.application -appmanifest MYAppName.exe.manifest
-certfile pfxfile.pfx -Password pfxFilePassword
So you are done. But there are a few points to remember. If your application’s DLLs are renamed with deploy, then you need to remove this option or the sign will not work. You can remove the .deploy option from Visual Studio property window > Publish Tab > Options.
Figure: Remove .deploy extension from Visual Studio.
Now you can write a batch file which you can run after build and the batch file will sign the clickonce manifests and your manifest signing is totally different from your development.