Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I bundle a Mono / GTK# application on Linux?

Here's the problem I'm running into: I wrote a Gtk# program using MonoDevelop and it runs great. But now I want to be able to run it on other Linux boxes without having to install MonoDevelop.

My solution has two projects: the main Gtk# application, and a C# library project upon which it depends. So when I build the main project, it makes MainProject.exe and MainProject.exe.mdb, along with DependencyProject.dll in the bin/Release folder.

I tried running the following command to package it all into a single executable (run from the bin/Release folder):

mkbundle MainProject.exe -o mainproject --deps *.dll

However, I get this error from running that command:

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.String assemblyString, System.Security.Policy.Evidence assemblySecurity, Boolean refonly) [0x00000] in :0

at (wrapper remoting-invoke-with-check) System.AppDomain:Load (string,System.Security.Policy.Evidence,bool)

at System.Reflection.Assembly.ReflectionOnlyLoad (System.String assemblyString) [0x00000] in :0

at IKVM.Reflection.Universe.DefaultResolver (System.String refname, Boolean throwOnError) [0x00000] in :0

at IKVM.Reflection.Universe.Load (System.String refname, IKVM.Reflection.Module requestingModule, Boolean throwOnError) [0x00000] in :0

at IKVM.Reflection.Universe.Load (System.String refname) [0x00000] in :0

at MakeBundle.QueueAssembly (System.Collections.Generic.List`1 files, System.String codebase) [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.String assemblyString, System.Security.Policy.Evidence assemblySecurity, Boolean refonly) [0x00000] in :0

at (wrapper remoting-invoke-with-check) System.AppDomain:Load (string,System.Security.Policy.Evidence,bool)

at System.Reflection.Assembly.ReflectionOnlyLoad (System.String assemblyString) [0x00000] in :0

at IKVM.Reflection.Universe.DefaultResolver (System.String refname, Boolean throwOnError) [0x00000] in :0

at IKVM.Reflection.Universe.Load (System.String refname, IKVM.Reflection.Module requestingModule, Boolean throwOnError) [0x00000] in :0

at IKVM.Reflection.Universe.Load (System.String refname) [0x00000] in :0

at MakeBundle.QueueAssembly (System.Collections.Generic.List`1 files, System.String codebase) [0x00000] in :0

I saw a few other Stack Overflow questions with similar problems but none of them offered any practical solutions. How do I use this mkbundle command effectively?

like image 463
soapergem Avatar asked Nov 10 '22 08:11

soapergem


1 Answers

mkbundle is great if you want a completely stand-alone application, that does not rely on mono or anything related to mono to be installed in the target machine.

However, in the mono pages, you can read that: "The resulting executable is self contained and does not need the Mono runtime installed to run. However, if your application relies on libraries linked to by the mono runtime or Gtk#, those will need to be installed (Gtk# helper libraries come to mind)."

If you just want to create a single executable from a few dll's, then ILRepack is a better choice.

If you are deploying to Windows, then you can just include the GTK# installer with your app (.NET is likely already present). If you are deploying to linux or mac, you need to have the mono packages (not necessarily mono-complete) installed before your app runs.

Hope this helps.

like image 88
Baltasarq Avatar answered Nov 15 '22 06:11

Baltasarq