mkbundle and GTK#

2019-02-16 04:48发布

问题:

I'm trying to use mkbundle so that I can distribute a GTK# application without users needing to install .NET/Mono or GTK#. I've successfully bundled an application which uses winforms, but for some reason when I do the same with a GTK# application it won't work.

This is what I get out of cygwin:

$ mkbundle --deps a.exe OS is: Windows Sources: 1 Auto-dependencies: True

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'gtk-sharp' or one of its dependencies. The system cannot find the file specified.
File name: 'gtk-sharp'
at System.AppDomain.Load (System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity) [0x00000] in :0
at (wrapper remoting-invoke-with-check) System.AppDomain:Load (System.Reflection.AssemblyName,System.Security.Policy.Evidence)
at System.AppDomain.Load (System.Reflection.AssemblyName assemblyRef) [0x00000] in :0
at (wrapper remoting-invoke-with-check) System.AppDomain:Load (System.Reflection.AssemblyName)
at System.Reflection.Assembly.Load (System.Reflection.AssemblyName assemblyRef) [0x00000] in :0
at MakeBundle.QueueAssembly (System.Collections.ArrayList files, System.String codebase) [0x00000] in :0
at MakeBundle.Main (System.String[] args) [0x00000] in :0
[ERROR] FATAL UNHANDLED EXCEPTION: System.IO.FileNotFoundException: Could not load file or assembly 'gtk-sharp' or one of its dependencies. The system cannot find the file specified.
File name: 'gtk-sharp'
at System.AppDomain.Load (System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity) [0x00000] in :0
at (wrapper remoting-invoke-with-check) System.AppDomain:Load (System.Reflection.AssemblyName,System.Security.Policy.Evidence)
at System.AppDomain.Load (System.Reflection.AssemblyName assemblyRef) [0x00000] in :0
at (wrapper remoting-invoke-with-check) System.AppDomain:Load (System.Reflection.AssemblyName)
at System.Reflection.Assembly.Load (System.Reflection.AssemblyName assemblyRef) [0x00000] in :0
at MakeBundle.QueueAssembly (System.Collections.ArrayList files, System.String codebase) [0x00000] in :0
at MakeBundle.Main (System.String[] args) [0x00000] in :0`

But yet I have /cygdrive/c/GtkSharp/2.12/lib in my PATH variable. I can check this, as if I type "gtk-sharp.dll" into cygwin I get the following returned:

$ gtk-sharp.dll bash: /cygdrive/c/GtkSharp/2.12/lib/gtk-sharp-2.0/gtk-sharp.dll: cannot execute binary file

So it should be able to find the file!

Any help would be much appreciated.

回答1:

I found a shell script which does all this and modified it to the latest versions, as of May 2013 you can just use the script as follows:

https://gist.github.com/tebjan/5581296

1.) Install cygwin and make sure you select the following packages: - gcc-mingw - pkg-config - mingw-zlib1 - mingw-zlib-devel

2.) Install the Mono release package: "Mono for Windows, Gtk#, and XSP"

3.) Download the script place it besides your Application and modify it to fit your environment (read the comments in the file carefully).

4.) Open cygwin and navigate to the output folder of your application where the ececutable and the scipt lies, e.g. YourProject/bin/Release

5.) Execute the script with the command: ./mkbundle_cygwin.sh

Troubleshooting: If your bundled executable does not work make sure the original .NET application works on mono. You can test that by calling mono.exe and pass your .NET app to it or by installing XamarinStudio and running your project from there (make you set mono as runtime).



回答2:

OK I don't know if this is a real solution, but I just copied the assemblies from C:\GtkSharp\2.12\lib\gtk-sharp-2.0 to C:\Mono-2.10.5\lib\mono\4.0 and now it seems to bundle ok using the following steps:

mkbundle -c -o host.c -oo bundle.o --deps app.exe

nano host.c

change the following from:

#ifdef _WIN32
#include <windows.h>
#endif`

to

#ifdef _WIN32
#include <windows.h>
#endif
#undef _WIN32

And finally:

gcc -mno-cygwin -o bundled.exe -Wall host.c `pkg-config --cflags --libs mono-2|dos2unix` bundle.o

That worked for me. Though I also for some things have needed to copy machine.config from C:\Mono-2.10.5\etc\mono\4.0 to the directory where my application is, and pass --machine-config machine.config to mkbundle.