System.BadImageFormatException When Installing Program From VS2010 Installer Project
I am getting this error when trying to install a Windows Service from a VS2010 .NET 4 Installer project:
"Exception occurred while initializing the installation: System.BadImageFormatExceptio开发者_运维百科n. Could not load the file [file name].exe or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded."
I can't figure out what is causing this. All the projects in my solution are compiling against .NET Framework 4 and the installer solution dependencies require .NET 4. I have cleaned/rebuilt the solutions and projects to no avail. Is there something obvious I am missing?
This can happen if your installer is installing 64-bit dlls.
If you add a 64-bit managed custom action to a Setup project, the Visual Studio build process embeds a 32-bit version of InstallUtilLib.dll into the MSI as InstallUtil. In turn, the 32-bit .NET Framework is loaded to run the 64-bit managed custom action and causes a BadImageFormatException exception.
For the workaround, replace the 32-bit InstallUtilLib.dll with the 64-bit version.
- Open the resulting .msi in Orca from the Windows Installer SDK.
- Select the Binary table.
- Double click the cell [Binary Data] for the record InstallUtil.
- Make sure "Read binary from filename" is selected and click the Browse button.
- Browse to %WINDIR%\Microsoft.NET\Framework64\v2.0.50727.
- The Framework64 directory is only installed on 64-bit platforms and corresponds to the 64-bit processor type.
- Select InstallUtilLib.dll.
- Click the Open button.
- Click the OK button.
You likely have the wrong installer prerequisites. Go to your setup project's properties window, click Prerequisites... under build, and ensure that .NET Framework 4 is checked. You likely still have .NET Framework 3.5 SP1 still checked. You probably need to use Windows Installer 4.1 as well (in the same dialog).
Also check to make sure that in launch conditions your .NET Framework version points to 4.
Maybe you could try to create a [yourfile.exe].config aside [yourfile.exe] like this:
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" />
</startup>
</configuration>
or maybe the machine you're installing to just does not have the Framework 4 installed?
I avoided having to hack at the installer with Orca (which invalidated my signature btw). I just added a new executable project called "InstallHelper" to my solution that compiled in x86 mode and added the custom action code to that. I then added the primary output of that project to the installer and set the custom actions in the setup project to run against that primary output instead of the 64 bit output from my main application. Now both my 32 bit and 64 bit setup projects run fine.
Alternatively, if you still face this issue you can set goto VS2010, under Build->Configuration Manager and set your Project Platform to "Any CPU".
Goto Solution Explorer and click on your MSI Setup project, you will be able to see "TargetPlatform" under properties. Set it to x64. Rebuild your MSI project and give it a try.
Building on @john and @snark, here is the automated way to perform @Greg Samsons answer. The goal is to inject the 64-bit version of InstallUtilLib.dll into your msi.
- Create Fix64bitInstallUtilLib.js in your installer project directory and copy the following code (taken from here):
// http://blogs.msdn.com/b/heaths/archive/2006/02/01/64-bit-managed-custom-actions-with-visual-studio.aspx
var msiOpenDatabaseModeTransact = 1;
var msiViewModifyUpdate = 2
var filespec = WScript.Arguments(0);
var projdir = WScript.Arguments(1);
var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);
// Update the Binary table...
var sql = "SELECT `Name`,`Data` FROM `Binary` where `Binary`.`Name` = 'InstallUtil'";
var view = database.OpenView(sql);
view.Execute();
var record = view.Fetch();
record.SetStream(2, projdir + "InstallUtilLib.dll");
view.Modify(msiViewModifyUpdate, record);
view.Close();
database.Commit();
Copy InstallUtilLib.dll to your installer project directory from %WINDIR%\Microsoft.NET\Framework64\[.NET version]
In PostBuildEvent, add:
Cscript.exe "$(ProjectDir)\Fix64bitInstallUtilLib.js" "$(BuiltOuputPath)" "$(ProjectDir)/"
精彩评论