Search code examples
c#macospinvokedllimport

How to get the clipboard text on OSX using DllImport with c#?


the following code sets the clipboard text on OSX. What is the equivalent to read the clipboard text?

static class OsxClipboard
{
    public static void SetText(string text)
    {
        var nsString = objc_getClass("NSString");
        var str = objc_msgSend(objc_msgSend(nsString, sel_registerName("alloc")), sel_registerName("initWithUTF8String:"), text);
        var dataType = objc_msgSend(objc_msgSend(nsString, sel_registerName("alloc")), sel_registerName("initWithUTF8String:"), NSPasteboardTypeString);

        var nsPasteboard = objc_getClass("NSPasteboard");
        var generalPasteboard = objc_msgSend(nsPasteboard, sel_registerName("generalPasteboard"));

        objc_msgSend(generalPasteboard, sel_registerName("clearContents"));
        objc_msgSend(generalPasteboard, sel_registerName("setString:forType:"), str, dataType);

        objc_msgSend(str, sel_registerName("release"));
        objc_msgSend(dataType, sel_registerName("release"));
    }

    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_getClass(string className);

    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_msgSend(IntPtr receiver, IntPtr selector);

    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_msgSend(IntPtr receiver, IntPtr selector, string arg1);

    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg1, IntPtr arg2);

    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr sel_registerName(string selectorName);

    const string NSPasteboardTypeString = "public.utf8-plain-text";
}

Solution

  • public static string GetText()
    {
        var nsString = objc_getClass("NSString");
        var nsPasteboard = objc_getClass("NSPasteboard");
    
        var nsStringPboardType = objc_msgSend(objc_msgSend(nsString, sel_registerName("alloc")), sel_registerName("initWithUTF8String:"), "NSStringPboardType");
        var generalPasteboard = objc_msgSend(nsPasteboard, sel_registerName("generalPasteboard"));
        var ptr = objc_msgSend(generalPasteboard, sel_registerName("stringForType:"), nsStringPboardType);
        var charArray = objc_msgSend(ptr, sel_registerName("UTF8String"));
        return Marshal.PtrToStringAnsi(charArray);
    }
    
    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_getClass(string className);
    
    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_msgSend(IntPtr receiver, IntPtr selector);
    
    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_msgSend(IntPtr receiver, IntPtr selector, string arg1);
    
    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr objc_msgSend(IntPtr receiver, IntPtr selector, IntPtr arg1);
    
    [DllImport("/System/Library/Frameworks/AppKit.framework/AppKit")]
    static extern IntPtr sel_registerName(string selectorName);