从VS2010安装程序项目安装程序时出现System.BadImageFormatException错误

4

当我尝试从VS2010 .NET 4安装程序项目安装Windows服务时,出现以下错误:

"初始化安装时发生异常:System.BadImageFormatException。无法加载文件[file name].exe或其某个依赖项。此程序集是由比当前加载的运行时更新的运行时构建的,因此无法加载。"

我不知道是什么原因导致这种情况。我的解决方案中的所有项目都编译针对.NET Framework 4,并且安装程序解决方案依赖项需要.NET 4。我已经清理/重建了解决方案和项目,但没有效果。我是否遗漏了一些明显的东西?

6个回答

13

如果您的安装程序正在安装64位dll,则可能会发生这种情况。

如果向设置项目添加64位托管自定义操作,Visual Studio构建过程将把32位版本的InstallUtilLib.dll嵌入到MSI中作为InstallUtil。然后,加载32位.NET Framework运行64位托管的自定义操作,从而导致BadImageFormatException异常。

解决方法是用64位版本替换32位的InstallUtilLib.dll。

  1. 在Windows Installer SDK中使用Orca打开生成的.msi文件。
  2. 选择“Binary”表。
  3. 双击InstallUtil记录的[Binary Data]单元格。
  4. 确保选择“从文件名读取二进制数据”,然后点击“浏览”按钮。
  5. 浏览到%WINDIR%\Microsoft.NET\Framework64\v2.0.50727。
  6. Framework64目录仅安装在64位平台上,并对应于64位处理器类型。
  7. 选择InstallUtilLib.dll。
  8. 点击“打开”按钮。
  9. 点击“确定”按钮。

谢谢。我已经为这个问题苦苦挣扎了好几天,现在终于解决了。 - Tim
我也遇到了这个问题,你的解决方案对我很有帮助。看起来应该有更简单的方法,或者至少有一种自动化的方式,但现在我会采用有效的方法。谢谢! - Tim
1
@Tim 如果你和我一样想要自动化这个过程,那么可以从https://code.msdn.microsoft.com/windowsdesktop/CSBrowserHelperObject-59c189a2#content(在底部附近阅读)获取一个javascript示例。将`Fix64bitInstallUtilLib.js`文件和适当版本的.Net框架目录中的64位版本的`InstallUtilLib.dll`复制到设置项目中。然后将`Fix64bitInstallUtilLib.js`作为设置项目的后期构建事件调用。有关详细信息,请参见示例。 - snark
谢谢。在空闲时间里,我尝试了一年多的时间来解决部署 Microsoft 项目扩展到 64 位版本的问题。检查了所有依赖库。分析了几 GB 的日志文件,最终发现罪魁祸首是设置项目中这个小淘气库。 - kikea
1
为了更新@Tim的例子,微软已经移动了该项目。但是你可以在GitHub上找到它:https://github.com/blak3r/openop/tree/master/CSShellExtContextMenuHandler/CSShellExtContextMenuHandlerSetup(x64)。 - John

3

您可能安装了错误的先决条件。进入您的设置项目的属性窗口,在“生成”下单击“先决条件...”,确保已选中.NET Framework 4。您可能仍然选中了.NET Framework 3.5 SP1。您可能还需要在同一对话框中使用Windows Installer 4.1。

另外,请检查启动条件,确保您的.NET Framework版本指向4。


1
也许你可以尝试创建一个与[yourfile.exe]相邻的[yourfile.exe].config文件,像这样:
<configuration>
  <startup>
    <supportedRuntime version="v4.0.30319" />
  </startup>
</configuration>

或者你要安装的机器上可能没有安装 Framework 4呢?


1
我避免了使用Orca对安装程序进行修改(这会使我的签名失效)。我只是在我的解决方案中添加了一个名为“InstallHelper”的新可执行项目,以x86模式编译,并将自定义操作代码添加到其中。然后,我将该项目的主输出添加到安装程序中,并将设置项目中的自定义操作设置为针对该主输出运行,而不是针对我的主应用程序的64位输出运行。现在,我的32位和64位安装项目都可以正常运行。

0

在@john和@snark的基础上,这里提供了一种自动化的方法来执行@Greg Samsons的答案。目标是将64位版本的InstallUtilLib.dll注入到您的msi中。

  1. 在您的安装程序项目目录中创建Fix64bitInstallUtilLib.js,并复制以下代码(取自此处):
// 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();
  1. 从%WINDIR%\Microsoft.NET\Framework64\[.NET版本]复制InstallUtilLib.dll到您的安装程序项目目录中

  2. 在PostBuildEvent中添加:

Cscript.exe "$(ProjectDir)\Fix64bitInstallUtilLib.js" "$(BuiltOuputPath)" "$(ProjectDir)/"

0

或者,如果您仍然遇到此问题,可以前往VS2010,在“构建” ->“配置管理器”下设置您的项目平台为“任何 CPU”。

转到解决方案资源管理器并单击您的MSI安装程序项目,您将能够在属性下看到“TargetPlatform”。将其设置为x64。重新生成您的MSI项目并尝试一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接