 |
|
 |
For those with a recent SDK there is an mt.exe (Manifest Tool) which can add a manifest to an exe.
E.g. http://msdn2.microsoft.com/en-us/library/aa375649.aspx[^]
Example post-build event:
mt /manifest "$(ProjectDir)MYAPPLICATIONNAME.exe.manifest" /outputresource:MYAPPLICATIONNAME.exe
if "$(ConfigurationName)"=="Debug" (copy "$(ProjectDir)MYAPPLICATIONNAME.exe.manifest" "$(TargetDir)MYAPPLICATIONNAME.exe.manifest")
Added the second line only if you want to debug an app from VS, because Visual Studio in debug mode will host the exe ('vshost'), so in that case the manifest seems to have to be external (VS automatically copies it the 'vshost exe' manifest on a debug session).
Has anyone else come up with a cleaner way...?
|
|
|
|
 |
|
 |
You can change your project settings to disable the vshost process.
|
|
|
|
 |
|
 |
Hi Acoustic,
Great and very useful article! Carrying a 'manifest' file together with the EXE it's a weak solution, because deleting that file affects the whole application. The injection solves this problem.
However, have you ever noticed that this xp-style affects combobox performance? This is an offtopic, but maybe you can help me. When you try to insert 2000 elements, using AddItem method, XP-Combobox consumes 2,5s instead of the habitual 0,5s. I've get those times compiling a project, and executing two identical EXE. Only one of this EXE had the manifest injected. The same code (inserting 2000 items) takes very diferent times on each application instance.
Very thanks in advance. I'm stuck with this problem.
|
|
|
|
 |
|
 |
Take a look at a few of the posts below. There are a few minor code changes you can make, but I don't know if they'll change performance much unless you have an exception being thrown. I haven't seen any performance issues, but I'll post a fix if I come across anything.
|
|
|
|
 |
|
 |
This, combined with the console code by another poster, works very well for us. Thanks!
You can even have the IDE ebed this for you using the build events. If you make your Post build event something like this:
$(ProjectDir)..\..\..\scripts\ManifestInjection.exe $(TargetFileName) $(ProjectDir)$(TargetFileName).manifest
We have the ManifestInjection as a console application in the scripts directory referenced in the command.
We had to do this because building from the command line worked great, but the application behaved quite a bit differently if we ran from the IDE directly.
|
|
|
|
 |
|
 |
Thanks! I'm glad to hear this project helps things works for you, and that it's a useful example.
|
|
|
|
 |
|
 |
Hi Tyler !
Great work !
I extended your sample and added a console application. This way I can call it from a visual studio project and inject a manifest file to a freshly compiled exe.
The call is put in the post build event. Here is part of the csproj file:
PostBuildEvent = "PATH_TO_MANIFESTINJECTOR\ManifestInjector.exe $(TargetPath) $(ProjectDir)\MY_EXECUTABLE.exe.manifest"
The code for the console app is this one:
static int Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine ("Usage: ManifestInjector.exe targetexe manifestfile");
//Failed...
return -1;
}
string strExe = args[0];
string strManifest = args[1];
Console.WriteLine("Inject manifest: '" + strManifest + "' into executable '" + strExe + "'");
//Do the files exist ?
if (File.Exists (strExe) == false)
{
Console.WriteLine ("Executable '" + strExe + "' does not exist !");
return -1;
}
if (File.Exists (strManifest) == false)
{
Console.WriteLine ("Manifest '" + strManifest + "' does not exist !");
return -1;
}
//Inject the manifest:
bool bolReturn = ManifestInjector.Inject (strExe, strManifest, 1);
if (bolReturn == true)
{
Console.WriteLine ("Injection succeeded !");
return 0;
}
else
{
Console.WriteLine ("Injection failed !");
return -1;
}
}
Best regards
Wolfgang
|
|
|
|
 |
|
|
 |
|
 |
Has anybody tried Manifest File Injection with files that are runned from an website (ie. href-exe, smart client, no touch deployment)??
I'm not able to get XP Theme at all in my applications when using this technique.
Best regards,
Geir Aamodt
geir.aamodt(AT)bekk.no
|
|
|
|
 |
|
 |
I found out why and how...
MyApp.exe is not running standalone in a NTD scenario, it is being
runned by the IEExec.exe process.
Hence, a manifest for the IEExec.exe must be created and placed in the directory
of the exe, typically in your the folder of your current version of the Framwork.
Best regards,
Geir Aamodt
geir.aamodt(AT)bekk.no
|
|
|
|
 |
|
 |
I tried your code with a signed assembly and it didn't work. It seems like UpdateResource is corrupting the assembly. Does you know how to inject a manifest file in a signed assembly? If I re-sign the assembly after injecting the manifest, the application still doesn't work.
Thnak you,
Louis
|
|
|
|
 |
|
 |
The whole point of signing an assembly is to prevent it from being changed after it's built. You need to use delay signing and sign it after the manifest is injected. There's tons of documentation on MSDN.
Best of luck.
|
|
|
|
 |
|
 |
I had the same problem, and sure enough resigning the assembly made my toolband start appearing again. So now I can add the .manifest and the IE toolband still shows itself.
the only problem is any button in the band appears as normal.
I can verify that the button is using the correct style by putting the manifest into the IExplore directory and calling it 'iexplore.exe.manifest' and the button shows itself with the correct XP styling.
Can anyone shed any light on this?
Paul Carroll
|
|
|
|
 |
|
 |
The whole point of signing an assembly is to prevent it from being changed after it's built. You need to use delayed signing and sign it after the manifest is injected. There's tons of documentation on MSDN.
Best of luck.
|
|
|
|
 |
|
 |
In your code you use the following:
if (UpdateResource(updatePointer, 24, ResourceName, 0, manifestByteArray,
(uint)manifestByteArray.Length) != 1)
I was wondering how you found out that 24 = RT_MANIFEST?
I am trying to use the UpdateResource in my project and found this article. BTW Great article
I need to embedd a file of type RT_RCDATA but cant find any info other than defining a Public constwhich just seems more messy. Can you help point me in the right direction?
I've looked everywhere, maybe i'm missing something?
Regards
Wayne Phipps
____________
Time is the greatest teacher... unfortunately, it kills all of its students
LearnVisualStudio.Net
|
|
|
|
 |
|
 |
I admin - it's sloppy code... and I'm a huge opponent of "magic numbers." the value 24 came right off of MSDN where the list the possible constants for that method call. Honestly, I found within two clicks of a Google search.
|
|
|
|
 |
|
 |
Did anyone tried to inject manifest into dll file?
Is it possible and will it enable visual styles?
Or maybe there is some other solution if I have usercontrol compiled in dll and used by unamanaged application?
Any ideas?
anything would be helpful...
--
PiT
" I Code Therefore I Am..."
|
|
|
|
 |
|
 |
I believe the host application controls the visual style settings. You should only have to set the flatstyle property to system.
|
|
|
|
 |
|
|
 |
|
 |
I’m not surprised they look the same. For one, it looks like this tool does the same thing mine does, only in c++. The similarities are due to the fact that the external DLL’s being called all share the same common names. “BeginUpdateResource,” “EndUpdateResource,” and “UpdateResource” would be the same for anyone. The COM Marshaling is also standard, and would be the same when no HRESULT is returned (i.e. Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); ) That’s all the major code in the method, so I’m not surprised that they look so similar. Plus, I got my idea from the MSDN article (wish it was original) I linked to in this article. I imagine this other project came from the same source. I’m going to have to email this guy and show him your post – what a cool observation!!
|
|
|
|
 |
|
 |
it's a lot easier to enable XP theme support by simply adding the following two lines before you call the method InitializeComponent();
Application.EnableVisualStyles();
Application.DoEvents(); // Workaround for bug in .NET Framework v.1.1
Regards,
Bram
|
|
|
|
 |
|
 |
You're right, but this only works on .NET Framework 1.1!
|
|
|
|
 |
|
 |
There are cases where those lines of code can cause an application to crash, and is designed to support Win NT based systems only. And the real power with this code is that you can enable styles for an application you don't have the source code for. The above lines are only a good solution for code you have access to.
|
|
|
|
 |
|
 |
There are other defects with using Application.EnableVisualStyles in v1.1. Granted, using Application.EnableVisualStyles would reduce the hassle of theme support if it worked properly.
If you spawn any forms from your main form, you will non-deterministically encounter SEHExceptions when the spawned form is closed. In addition, sometimes the forms spawned are not themed (and then when they are closed they throw an SEHException). We ran into this continually here at work on our last project, so we used the manifest file instead. The manifest file does not cause the SEHException issue (and actually works like it should), which made it our theming method of choice.
|
|
|
|
 |
|
 |
Did you test calling Application.DoEvents() just after Applications.EnableVisualStyles. It solved my SEHExceptions and now I can forget the manifest file.
Jose
|
|
|
|
 |