Jan 232011
 

Reading clipboard in .NET is fairly straightforward.

   var text = Clipboard.GetText();

Once you stumble into Mono under Linux, things tend to change. Clipboard works only inside your application, rest of system works on different plane altogether. In order to get text from system clipboard we need to have following code:
    Gtk.Clipboard clippy = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
    var text = clippy.WaitForText();

And here comes the problem. These functions need reference to both gdk-sharp and gtk-sharp. Unfortunately this also means that you cannot run it without MONO runtime. You can forget running application under Microsoft’s .NET Framework. Even if we don’t use those functions our applications will fail upon startup since it cannot resolve all references.

I solved this issue by having separate .dll for clipboard operations on Linux but I haven’t created any reference to it. In order to determine clipboard content I use reflection to load it (only if we are on Mono):

private string GetClipboardText() {
    if (IsRunningOnMono) {
        var fullExePath = new FileInfo(Assembly.GetExecutingAssembly().Location);
        var gtkAss = Assembly.LoadFile(Path.Combine(fullExePath.DirectoryName, "GtkClipboard.dll"));
        var assMethod = gtkAss.GetTypes()[0].GetMethod("GetGtkText");
        txtClipboard.Text = assMethod.Invoke(null, new object[] { }) as string;
    } else {
       txtClipboard.Text = Clipboard.GetText();
    }
}

private static bool IsRunningOnMono {
    get {
        return (Type.GetType("Mono.Runtime") != null);
    }
}

And what should we put in our .dll? It ends up that it is quite simple code:

public static class Clipboard {
    public static String GetGtkText() {
        Gtk.Clipboard clipboard = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
        if (clipboard != null) {
            return clipboard.WaitForText();
        } else {
            return "";
        }
    }
}

P.S. You will notice here that reflection code loads first class that comes in array. Since I only have one class in that whole .dll this is not an issue. If you add more classes to that assembly take care that you select correct one.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>