VB6 + Manifest Creation and Embedding.
First, what I’m trying to accomplish is not XP Visual Styles or any of that mess. I’m only after ensuring that the application runs as Administrator on Windows Vista-10 boxes, so it functions properly.
I’ve found numerous resources on manifest creation and embedding, all in various locations with some different techniques, all seem to involve a convoluted process of embedding the manifest, and even creation is wacky with padding the manifest to an even 1k or 4k or whatever to get it to work properly.
Nonsense! Here’s what this idiot learned to make it all come together.
First, manifest creation. Here is the manifest file I use, and I’ll tell you a few things about it’s settings. (Updated for Windows 10!)
Now, I believe the only thing you NEED to actually change is the EXE name, but honestly I haven’t even tested to see if that can be whatever. You will of course WANT to change everything I put in caps, to suit your needs. Changing the version number of the application inside the manifest file doesn’t seem to be necessary when your app version number changes, I’ve not seen this to cause any issues in running the app.
The file is otherwise pretty self-explanatory, you see the “requestedExecutionLevel” should be “requireAdministrator“, of course. Other options are “highestAvailable” and the most commonly used “asInvoker“.
In many posts I see that uiAccess=”true” however that worked intermittently for me, I forget what it does, but it is supposedly only for Windows services. Either way setting it to “false” gives consistent results across platforms, it just works for my purposes, even for Windows services…
Of course, you save that as plain text. The proper way to include a manifest file with your application is to name it APPNAME.EXE.MANIFEST – using your application name exactly as the prefix, and don’t forget the .EXE before the .MANIFEST or you will pull your hair out trying to figure out what was wrong. Maybe I was stoned when I did that, haha. My sample is named .txt at the end but you should remove that, the .txt is only there on the server for the correct plain text mime type when downloading.
Test your manifest prior to embedding – simply include it in the same directory as the EXE and run the EXE on a system with UAC enabled, you should get the elevation prompt if you are using the requireAdministrator flag as specified in the sample. Once that works, proceed!
Second, Manifest Embedding. I stumbled upon a super easy way to embed manifests into VB6 applications. Thanks to Chris001 at vbforums.com, in this thread: http://www.vbforums.com/showthread.php?t=475968
You will need Resource Hacker, an oldie (but goodie) freeware app from http://angusj.com/resourcehacker/
1. To do the trick, as Chris001 writes, fire up the tiny Resource Hacker and open your compiled and almost ready to ship executable.
2. Click Action > Add a new Resource and select your manifest file.
3. Set the Resource Type to 24, the Resource Name to 1, and the Resource Language to 1033. This of course means you can’t already have an existing resource in your EXE named “1” …
4. Now save the new file. Voila, done.
If you aren’t trying to mess around with XP visual styles, then you’re done with the project, congrats!
If you needed XP visual styles, read on.
First, you’ll need to add this to your manifest file before embedding: (lines are numbered to combat word wrap)
- <assemblyIdentity language=”*” name=”Microsoft.Windows.Common-Controls” processorArchitecture=”X86″ publicKeyToken=”6595b64144ccf1df” type=”win32″ version=”22.214.171.124″ />
Just tack it onto the end BEFORE the last line “</assembly>”
Chris001 also writes that you need to include some code in your project prior to compile, which calls the InitCommonControls function of comctl32.dll – this isn’t necessary if you are only creating the manifest for the purposes I have described, no visual stuff just elevation to Administrator on UAC enabled versions of Windows.
But here is the code, in case that link to Chris001’s post ever ceases to be, and you are going for visual styles as well. I numbered the lines to help with word wrap.
1. Private Declare Function InitCommonControls Lib “comctl32.dll” () As Long
2. Private Sub Form_Initialize()
4. End Sub
Or better yet, just read this article from vbaccelerator.com:
I should put in a strong note for those who might get frustrated. I’ve noticed strange behavior in that sometimes (and I can’t figure out when it’s ok and when it’s not) but SOMETIMES depending on your code, InitCommonControls must be called before the first form is loaded or the app won’t start with the manifest embedded or in the same directory. So if you have problems with your application starting perfectly in the IDE, and at first when compiled, but not with the manifest embedded or in the same directory, (the app fails to start or immediately crashes with no error or warning) then you should put InitCommonControls in a module and call it from Sub Main before the first form loads, and that would fix the issue.
But as I stated, this last bit about comctl32.dll and InitCommonControls is NOT needed for mere privilege elevation.
It really was that easy.