【问题标题】:Mono mkbundle throws 'IKVM.Reflection.BadImageFormatException'Mono mkbundle 抛出“IKVM.Reflection.BadImageFormatException”
【发布时间】:2014-11-19 15:13:52
【问题描述】:

我一直在尝试使用 mkbundle 编译或捆绑我的应用程序。 这是我正在执行的脚本:

set -o errexit
set -o nounset

mono_version="3.2.3"
export MONO=/cygdrive/c/progra~2/Mono-$mono_version

machineconfig=$PROGRAMFILES\\Mono-$mono_version\\etc\\mono\\4.0\\machine.config

export PATH=$PATH:$MONO/bin

export PKG_CONFIG_PATH=$MONO/lib/pkgconfig

icon_name='"icon.ico"'

echo "1 ICON $icon_name" > icon.rc

export CC="i686-pc-mingw32-gcc icon.o -U _WIN32"

output_name=Output.exe

mkbundle JiraTempoApp.exe MonoPosixHelper.dll gtk-sharp.dll glib-sharp.dll atk-sharp.dll gdk-sharp.dll glade-sharp.dll glib-sharp.dll pango-sharp.dll RestSharp.dll JiraRestLib.dll --deps --machine-config "$machineconfig" -o $output_name -z

rm icon.rc 
rm icon.o

cp $MONO/bin/mono-2.0.dll .
cp $MONO/bin/zlib1.dll .

./$output_name

我不得不添加 MonoPosixHelper.dll,因为我得到了一个 EntryPoint not found 错误。现在我得到了这个奇怪的错误:

$ ./mkbundle_cygwin.sh
OS is: Windows
WARNING:
  Check that the machine.config file you are bundling
  doesn't contain sensitive information specific to this machine.
Sources: 11 Auto-dependencies: True

Unhandled Exception:
IKVM.Reflection.BadImageFormatException: Exception of type 'IKVM.Reflection.BadImageFormatException' was thrown.
  at IKVM.Reflection.Reader.PEReader.RvaToFileOffset (UInt32 rva) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader.Read (System.IO.Stream stream) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader..ctor (IKVM.Reflection.Reader.AssemblyReader assembly, IKVM.Reflection.Universe universe, System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.String path) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.LoadFile (System.String path) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssembly (System.String assembly) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssemblies (System.Collections.Generic.List`1 sources) [0x00000] in <filename unknown>:0
  at MakeBundle.Main (System.String[] args) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: IKVM.Reflection.BadImageFormatException: Exception of type 'IKVM.Reflection.BadImageFormatException' was thrown.
  at IKVM.Reflection.Reader.PEReader.RvaToFileOffset (UInt32 rva) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader.Read (System.IO.Stream stream) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader..ctor (IKVM.Reflection.Reader.AssemblyReader assembly, IKVM.Reflection.Universe universe, System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.String path) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.LoadFile (System.String path) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssembly (System.String assembly) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssemblies (System.Collections.Generic.List`1 sources) [0x00000] in <filename unknown>:0
  at MakeBundle.Main (System.String[] args) [0x00000] in <filename unknown>:0

我的 .exe 已在 Windows 和 Ubuntu 上成功运行,但我正在尝试捆绑它,以便用户不必下载单声道。

【问题讨论】:

    标签: c# deployment mono mkbundle


    【解决方案1】:

    mkbundle 无法将动态链接库作为MonoPosixHelper.dll 处理。 如果您希望应用程序在没有单声道的情况下运行,则需要将此(和其他库)与您的应用程序一起部署在目标系统上。

    如果您想在 Ubuntu 上运行您的应用程序并且不希望用户安装 libgtk2.0-cil,您还必须部署 libatksharpglue-2.so libgdksharpglue-2.so libglibsharpglue-2.so libgtksharpglue-2.so libpangosharpglue-2.so,因为 *-sharp.dlls 需要它们。

    然后确保目标系统能够找到这些库。通过定义 LD_LIBRARY_PATH 或在构建系统上创建 DLL 映射(这很棘手并且可能有点乏味)。

    您还可以将--static 参数传递给mkbundle 以将所有需要的单声道库直接包含在您的包中(有关详细信息,请参见手册页)。 此外,仅使用 MyApp.exe 而非 mono MyApp.exe 执行您的最终包。

    以下是针对 Linux 目标执行此操作的一些选项。我还没有在 Windows 上将 mkbundle 与单声道一起使用,但仅使用 msbuild 针对 .NET 进行编译,这也会创建 .msi 文件。

    选项 1:

    $DEPS = "gtk-sharp.dll glib-sharp.dll atk-sharp.dll gdk-sharp.dll glade-sharp.dll glib-sharp.dll pango-sharp.dll RestSharp.dll JiraRestLib.dll"
    mkbundle --static -o JiraTempoApp JiraTempoApp.exe --deps $DEPS --machine-config "$machineconfig" -z
    

    然后确保部署MonoPosixHelper.dll。和上面描述的其他.so 文件到您的系统。要启动您的应用程序,请执行

    LD_LIBRARY_PATH=/path/to/deployed/libs:$LD_LIBRARY_PATH JiraTempoApp
    

    但是,我目前无法验证这种设置 LD_LIBRARY_PATH 的方法是否有效。

    选项 2:

    使用与选项 1 中相同的命令进行构建,但从已部署库的目录执行:

    cd /path/to/deployed/libs; /path/to/JiraTempoApp
    

    选项 3:

    这有点复杂:你需要在你的构建系统上找到你的依赖.dlls 和它们的.dll.config 文件。将它们复制到您的构建目录和配置文件中的 dll 映射,该映射包含到 target 系统上.so 文件位置的相对路径。 这样,dll 映射被 mkbundle 打包,打包后的可执行文件将能够在目标系统上找到已部署的.sos。 我曾经为使用此选项的应用程序写过Makefile,也许它会对您有所帮助。

    【讨论】:

    • 你能给我一个我应该执行的命令的例子吗
    • @sburnicki 我正在尝试在 MacOSX 上使用您的方法 3。我尝试复制此处提到的所有 dylib 和胶水文件 ascend4.org/Porting_to_Mac/gtk-mac-bundler 。它不起作用。我需要设置配置路径还是什么。请建议。
    【解决方案2】:

    您确定 MonoPosixHelper.dll 是托管库吗? AFAIK mkbundle 只能在托管代码上工作。您仍应使用此 DLL(将其保留在将加载它的文件夹中,例如您使用 LD_LIBRARY_PATH 定义的文件夹中)以避免 EntryNotFound 异常,但您不应将其用作 mkbundle 命令的参数。

    【讨论】:

    • 我已经尝试过了,但是编译后我在尝试执行时收到错误无效的 CIL 图像。
    • 那是我的全部错误。当我执行 mono Myapp.exe 时,我得到:无法执行程序无效的 CIL 图像。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多