Introduction
Recently I had the task of deploying an MFC application suite along with its
dependencies via ClickOnce. Visual Studio does not directly support deployment
of MFC applications (even if it's compiled with /clr) and one of the suggested
solutions I found on the web was to have a stub C# executable which would launch
the main MFC application. That way you could take advantage of Visual Studio's
built-in deployment functionality. My friend
Rama Vavilala had
a better suggestion for me - he asked me to try putting in a dummy cpp file into
the main project that was compiled using /clr. If ClickOnce accepted such an
executable as a .NET assembly, then all I would have to do would be to create
the required manifest files on my own. Well all I can say is hats off to Rama
for his elegant solution - because it actually did work. This article is a
step-by-step pictorial on how you would deploy an MFC application using this
trick.
Steps to deploying the MFC app
For my example I will use a simple MFC dialog application - but you can use
the same technique with a real application with dependencies (both managed and
native) and it will work (and I have got it to work).
Step 1 - Add the dummy /clr file
Add a new cpp file to your project and leave it empty. Change its compilation
setting to use /clr and remove support for precompiled headers. You would also
have to tweak a couple of other settings to allow the /clr compilation mode
depending on your main project settings. Now build the app. Even though you have
an empty /clr cpp unit in the project, you'll find that the app is a .NET app
for all purposes (you can verify this by opening the app in reflector).
Step 2 - Create a deployment folder and share it
Obviously in your case your deployment folder may be an FTP URL or a web URL
- so please change it accordingly. I just used a shared network path in my
machine. I created a folder called AppDeploy (which was shared
using the same name on the network) and I copied the MFC application into that
folder. If you have dependencies, you need to copy those files to the folder
too.
Step 3 - Create the application manifest
You don't need to do this from scratch. Instead you can use the mageui
utility to create a default app manifest. The first step would be to specify the
name of the application, the version, and the processor type. See the screenshot
where I've highlighted out the relevant changes.
Step 4 - Populate the files
You can auto-populate the required files by specifying the application
directory. It will auto-detect the main application (though if you have multiple
executables, you might need to manually fix this).
Step 5 - Signing the app manifest
You can leave the rest of the settings as they are and save the file - you'll
get a sign dialog as shown above. Since this is the first time, use the [New]
button to create a new certificate. If your company has a real certificate to
use, then you'd obviously be using that instead.
Step 6 - Creating the deployment manifest
The next step is to create the deployment manifest, using the same name and
version as the application manifest. Remember to set the processor to x86.
Step 7 - Setting the app description
This step is optional, but this is the information that the ClickOnce dialog
will show the end-user when he tries to run the app. So you might want to put
some decent information in there.
Step 8 - Setting ClickOnce deployment options
I've chosen install locally - so the app gets cached each time (unless
there's a newer version out). I've also set a start location for the ClickOnce
application. Your URL would obviously be different.
Step 9 - Setting the update options
I've used the default update options, but you can play with these settings to
find one that better suites your needs.
Step 10 - Referencing the app manifest
This is where you associate the app manifest with the deployment manifest.
The mageui utility will fill up the required information
automatically from the manifest.
Step 11 - Save and sign the deployment manifest
You can use the same key you used earlier to sign the manifest during saving.
Note that you can use a different key to sign the deployment manifest if you
want that.
Done
That's it. You can try running the application via the ClickOnce URL and
you'll see that the app deploys and runs fine.
Updating the manifests via a batch file
If you update the executable or one of its dependencies, you'll find that
it's not enough to just update the deployment folder. You have to re-sign the
manifests and also add newly added dependencies. You will also need to change
the version number to let ClickOnce correctly update the local version with an
update from the server. I've written a simple batch file that you can use.
Please change the folder and file names accordingly. The batch file (Update.bat)
looks as shown below :-
@call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86
mage -u ".\MfcDialog\MFC Application.exe.manifest" -fd .\MfcDialog\ -v %1
mage -u ".\MfcDialog\MFC Application.exe.manifest" -cf .\MfcApp.pfx
mage -u .\MfcApp.application -appm ".\MfcDialog\MFC Application.exe.manifest" -v %1
mage -u .\MfcApp.application -cf .\MfcApp.pfx
I've used the command line mage utility (mageui is basically a
UI version of mage - now there's a surprise!). The first call to
mage updates the files and sets the version on the app manifest. The next
call signs the app manifest. Then we run mage again, this time on the
deployment manifest, so it correctly updates the app manifest details. And
finally, we sign the deployment manifest. You have to sign both manifests each
time as the file contents change whenever you change anything.
You can run it via the command like as :-
>Update 1.0.0.3
Typical output would be :-
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
MFC Application.exe.manifest successfully updated
MFC Application.exe.manifest successfully signed
MfcApp.application successfully updated
MfcApp.application successfully signed
Okay. That's it really. You can play with and tweak various options to match
your requirements. If you have any suggestions, feedback or criticism, those are
welcome. I hope someone gets some use out of this article - since I am not very
sure that there are going to be lots of folks who want to use ClickOnce for
deploying their MFC applications.
Acknowledgements
- Rama Vavilala (blog)
- For the dummy /clr trick
History
- Jan 12, 2008 - First version of the article