Suppose you have a 32 bit .NET Windows application (whether it is a console or GUI Windows application (the latter in .NET a so-called Windows Forms app)) and you want to run it on a 32 bit Windows system. It doesn’t matter if you start it from Windows Explorer, from Command Prompt, from PowerShell (PS), through ClickOnce or start it directly from Internet Explorer (IE). In the last case IEExec.exe is started and your 32 bit .NET (version 1, 2 or 3) application is run within this process. IEExec is a runtime host for .NET (version 1, 2 or 3) applications in the scenario where the .NET executable is referred to via an URL provided to IE. For example, suppose you have a .NET GUI application hosted on a web server (no no, I’m not talking about a .NET WUI application, I am talking about a .NET GUI application (an .exe file and possibly a few DLLs) hosted by a web server like IIS, just like any other kind of file can be hosted by a web server. This type of deployment is called No-Touch Deployment aka Zero Deployment). The URL is something like http://servername:port/vdir/application.exe. You open IE, type or paste this URL in the address bar and let IE do its job. The IEExec.exe process will be created and the application.exe will run within this process, as IEExec is the runtime host in this scenario.
So far so good. But what if we want to run our application on a 64 bit Windows. Let’s see what happens if we open Windows Explorer and browse to the location of application.exe. We open the executable from within Windows Explorer and what happens next depends. If your application has been built for x86 (32 bit), it will run fine. Windows sees it’s dealing with a 32 bit application and thus it will run like any other 32 bit application on a 64 bit Windows. If your application was compiled for “Any CPU”, Windows will try to run it as a 64 bit application. This shouldn’t be a problem, except when your application isn’t really 64 bit compatible, for example when you use a 32 bit Oracle driver. In this case compiling to “Any CPU” was a bad decision, you must have compiled for 32 bit only. The solution in this scenario is to recompile or, if not possible, corflag the executable. By using the CorFlags Conversion Tool (CorFlags.exe) you can mark a .NET executable explicitly as a 32 bit application, just as you would have compiled it for 32 bit only (you only need to corflag the .exe files, not necessarily the DLL assemblies). Problem solved, right? Well, yes and no. If you start the application in Windows Explorer: yes. If you browse to the application through IE: no. IE will start IEExec.exe, which will try to run the for 32 bit compiled or corflagged application, but this will definitely fail, i.e. with a Microsoft IE Execute shell dialog box telling you the exception System.BadImageFormatException has been thrown (see the screenshots below). It doesn’t matter if you do this from the 32 bit or 64 bit version of IE.
This seems very weird, doesn’t it? You have a .NET application which is made explicitly for 32 bit (by compiling or corflagging), you can start it as a 32 bit application no matter how you start it (from Windows Explorer for example), even on a 64 bit Windows system, but this fails when you start it from (32 bit or 64 bit) IE on a 64 bit Windows system. Huh? Don’t panic, your application is fine and you don’t experience a virus or a bug 🙂 The thing is the 32 bit version of IE starts an IEExec.exe from the 32 bit Framework folder (C:\Windows\Microsoft.NET\Framework), while the 64 bit version of IE starts an IEExec.exe from the 64 bit Framework folder (C:\Windows\Microsoft.NET\Framework64). All IEExec.exe files are compiled for “Any CPU”, which means that IEExec.exe always starts as a 64 bit process on a 64 bit Windows. This means a 64 bit runtime host should start and run a 32 bit .NET application and that’s why IEExec.exe sees a bad image format and throws an exception of the type System.BadImageFormatException. And that’s also why the fact that you used a 32 bit IE didn’t make a difference; the error has nothing to do with IE! Note: there could be other causes for this exception, so getting this exception doesn’t necessarily mean a 64 bit IEExec tried to run a 32 bit application! Another cause could be that your application runs as 64 bit, but refers to a 32 bit unmanaged DLL. For still other causes and more information, check the Remarks section of this MSDN page: http://msdn.microsoft.com/en-us/library/system.badimageformatexception.aspx.
If you read this article, the chance exists you experience this error, right? And the previous piece of text doesn’t probably interest you, right? You have searched the Net for hours trying to find a solution and you’re quite desperate. Right? Well, prepare for relief! The only way to workaround this problem is to corflag IEExec.exe. Why? Well, if you corflag IEExec.exe to mark it explicitly as a 32 bit only application, it will always run as a 32 bit application, even on a 64 bit Windows system. And a 32 bit runtime host is just what we need to run our 32 bit .NET application! I must stress the fact that you only have to corflag IEExec.exe when your application is started from IE: if you start it from Windows Explorer, the command line,… IEExec.exe isn’t used at all!
Be aware of the fact that this is a workaround, not a real solution. You are tampering an official Microsoft file and that’s never Microsoft’s intention. So in a way your system isn’t 100% clear anymore. Secondly, I think this also means this isn’t supported by MS, so if you need to open a support call… Last but not least, your security is reduced. Yup, the thing is IEExec.exe is digitally signed by Microsoft and if you corflag the file, then you’re actually changing the file, making the digital signature invalid. You’re still able to run IEExec, but it’s not secured by a digital signature anymore. If your IEExec.exe is replaced by a malicious piece of software, you probably won’t even notice and even if you do it could be already too late… Because of these reasons I strongly advise not to corflag IEExec.exe, except when you don’t have another choice. For example, if you can’t make your application completely 64 bit compliant (in time or at all) and it must definitely run on 64 bit Windows (on the company’s new 64 bit RDSH environment for example) and your applications are started through IE (consider another way to start up your software though!), then I guess you don’t have a real choice: corflag IEExec.
You should ask yourself which IEExec.exe files to corflag, because probably several of these files exist on your system. First of all, there is a chance you have different versions of .NET Framework installed; some of them have their own IEExec.exe files. Secondly, some versions have a 32 bit and 64 bit folder. This means there is a decent chance you have more than 1 folder with an IEExec.exe file. Create an inventory of all the applications that need IEExec (that is, every application that should be able to start from IE) and that should run as 32 bit. Find out the highest version of the .NET Framework needed. For this version you need to corflag IEExec.exe. A second choice to make is for which IE (x86 or x64) you want the exe corflagged. Corflag the IEExec of the 32 bit Framework folder if you want to be able to start your application(s) from the x86 IE, just like you must corflag the IEExec of the 64 bit Framework folder if you need to be able to start your application(s) from the x64 IE.
Be aware though that corflagging IEExec for 32 bit means IEExec can’t run anymore as a 64 bit application and thus can’t host 64 bit .NET applications anymore. For example, suppose you corflag the IEExec.exe files for .NET Framework 2.0 as 32 bit only. If you start a 64 bit .NET application from IE made for .NET Framework 2.0, the application will fail to run. If you start the 64 bit application through another way (Windows Explorer for example) or if the 64 bit application needs another version of the Framework, then you shouldn’t experience any problem. One thing you could do is corflag the IEExec.exe of the 32 bit framework folder and leave the IEExec.exe file of the 64 bit framework folder alone. This way you can start 32 bit .NET apps through the 32 bit IE and still run 64 bit .NET apps through the 64 bit IE (or even the other way around if you want, depending on how you like it). If you don’t want to explain your users how, when and why they need to open different Internet Explorers for different applications, then you’re screwed 🙂 Or you could provide them with shortcuts, so they don’t have to open IE explicitly, let alone know which IE to open for which application.
Some background information
The CorFlags Conversion Tool (CorFlags.exe) was introduced with .NET Framework 2.0 and can be found in the Microsoft Windows SDK. The last version of this SDK is 7?1, also called “Microsoft Windows SDK for Windows 7 and .NET Framework 4”. To mark a file as 32 bit explicitly you need to use the switch “/32BIT+” and to remove this mark you use the switch “/32BIT-“ (both without the quotes). A file can only be corflagged if it’s a .NET assembly. If the assembly is strong named (signed), you must also use the “/Force” switch. After corflagging it’s advisable of course to resign the assembly, except when you really can’t do this (like with IEExec.exe for example). The latest version of the SDK (at the time of writing) can be found in the Microsoft Download Center: http://www.microsoft.com/downloads/en/details.aspx?familyid=6b6c21d2-2006-4afa-9702-529fa782d63b&displaylang=en.
Starting from Vista extra security measures are implemented in Windows. Replacing the IEExec.exe file just doesn’t work by default, even if you’re an administrator. First of all you need to take ownership of the file and then you need to give you the necessary permissions (for example, Full control). Then you can deal with the file the way you want. This way you can delete the file and copy or move the corflagged IEExec.exe (which you had copied earlier to a temporary location where you’ve corflagged it) to the framework folder. Remember to set the permissions to the original permissions again:
• SYSTEM: “Read & Execute” and “Read”
• Administrators: “Read & Execute” and “Read”
• Users: “Read & Execute” and “Read”
• TrustedInstaller: “Full control”
TrustedInstaller can be added to the ACL by typing the account “NT SERVICE\TrustedInstaller” for the “computer domain”. Also, make TrustedInstaller again the owner of the file.
IEExec.exe is in fact a quite undocumented application from Microsoft, part of the .NET Framework. IE 5.01 and later download assemblies to the assembly download cache and create a new IEExec.exe process to run the executable reffered to by the URL (possible files related to this program are then downloaded too, including possible DLL assemblies). IEExec sets up a runtime environment with constrained security, just as IE knows this (for example, the concept of zones is used in IEExec.exe too, what explains why .NET applications referred to through IE have another way of starting up: to get a typical “IE environment”, which is different than the default environment). If you want such an environment with constrained security without having to go through the browser process, you can run IEExec.exe from the command line and providing the URL as a parameter (perhaps you could even provide users with shortcuts for those commands instead of shortcuts to IE). IEExec.exe from .NET Framework 1.0 can receive extra parameters like the desired zone, but starting from .NET Framework 1.1 only the URL is accepted as a parameter. The latest version (2.0.50727.4927) belongs to .NET Framework 2.0 and is used for later versions of the .NET Framework (3.0 and 3.5) till the introduction of .NET Framework 4.0, which doesn’t support this mechanism anymore.