Mono mkbundle抛出'IKVM.Reflection.BadImageFormatException'

时间:2014-11-19 15:13:53

标签: c# deployment mono mkbundle

我一直在尝试使用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错误。现在我遇到了这个奇怪的错误:

$ ./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上成功运行,但我尝试捆绑它以便用户不必下载单声道。

2 个答案:

答案 0 :(得分:1)

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上使用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,也许它会帮助你。

答案 1 :(得分:0)

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

相关问题