Mono mkbundle throws 'IKVM.Reflection.BadImageFormatExce
本文关键字:IKVM Reflection BadImageFormatExce mkbundle throws Mono | 更新日期: 2023-09-27 18:31:14
我一直在尝试使用 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上成功运行,但我正在尝试捆绑它,以便用户不必下载单声道。
mkbundle
无法将动态链接的库处理为MonoPosixHelper.dll
。如果您希望应用程序在没有单声道的情况下运行,则需要将此库(和其他库)与应用程序一起部署在目标系统上。
如果你想在 Ubuntu 上运行你的应用程序,并且不希望用户安装 libgtk2.0-cil,你还必须部署libatksharpglue-2.so libgdksharpglue-2.so libglibsharpglue-2.so libgtksharpglue-2.so libpangosharpglue-2.so
,因为*-sharp.dll
需要它们。
然后确保目标系统能够找到这些库。通过定义LD_LIBRARY_PATH
或在构建系统上创建 DLL 映射(这很棘手,可能会变得有点乏味)。
您还可以将 --static
参数传递给 mkbundle
,以便将所有需要的单声道库直接包含在捆绑包中(有关详细信息,请参阅手册页)。此外,仅使用 MyApp.exe
而不是使用 mono MyApp.exe
执行最终捆绑包。
以下是针对 Linux 目标执行此操作的一些选项。我还没有在Windows上使用带有mono的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:
这有点复杂:你需要找到你是构建系统上的依赖项.dll
及其.dll.config
文件。将它们复制到生成目录和配置文件中的 dll 映射,其映射包括目标系统上.so
文件位置的相对路径。这样,dll 映射由 mkbundle 打包,打包的可执行文件将能够在目标系统上找到已部署的.so
。我曾经为使用此选项的应用程序编写了一个 Makefile,也许它会对您有所帮助。
你确定 MonoPosixHelper.dll 是一个托管库吗?AFAIK mkbundle 只能处理托管代码。您仍应使用此 DLL(将其保留在将加载它的文件夹中,例如使用 LD_LIBRARY_PATH 定义的文件夹中)以避免 EntryNotFound 异常,但不应将其用作 mkbundle 命令的参数。