.Net Core - copy to clipboard?

前端 未结 6 964
耶瑟儿~
耶瑟儿~ 2020-12-08 04:28

Is it possible to copy something to the clipboard using .Net Core (in a platform-agnostic way)?

It seems that the Clipboard class is missing, and P/Invoking is

6条回答
  •  猫巷女王i
    2020-12-08 04:39

    Necromancing.
    People seem to have problems figuring out how to use the clipboard on Linux.

    Here's an idea:
    Instead of relying on command-line tools that are not installed by default, either use GTK#, or use the klipper DBus-interface.
    Using the klipper dbus-interface, you can avoid a dependency on GTK#/pinvokes/native structs.

    Note: klipper must be running (which it is, if you use KDE). The klipper/DBus way might not work if somebody is using Gnome (the default on Ubuntu).

    Here's the code for the Klipper DBus-Interface (a bit large for stackoverflow):
    https://pastebin.com/HDsRs5aG

    And the abstract class:
    https://pastebin.com/939kDvP8

    And the actual clipboard-code (requires Tmds.Dbus - for handling DBus)

    using System.Threading.Tasks;
    
    namespace TestMe
    {
        using NiHaoRS; // TODO: Rename namespaces to TestMe
    
        public class LinuxClipboard
            : GenericClipboard
    
        {
    
            public LinuxClipboard()
            { }
    
    
            public static async Task TestClipboard()
            {
                GenericClipboard lc = new LinuxClipboard();
                await lc.SetClipboardContentsAsync("Hello KLIPPY");
                string cc = await lc.GetClipboardContentAsync();
                System.Console.WriteLine(cc);
            } // End Sub TestClipboard 
    
    
            public override async Task SetClipboardContentsAsync(string text)
            {
                Tmds.DBus.ObjectPath objectPath = new Tmds.DBus.ObjectPath("/klipper");
                string service = "org.kde.klipper";
    
                using (Tmds.DBus.Connection connection = new Tmds.DBus.Connection(Tmds.DBus.Address.Session))
                {
                    await connection.ConnectAsync();
    
                    Klipper.DBus.IKlipper klipper = connection.CreateProxy(service, objectPath);
                    await klipper.setClipboardContentsAsync(text);
                } // End using connection 
    
            } // End Task SetClipboardContentsAsync 
    
    
            public override async Task GetClipboardContentAsync()
            {
                string clipboardContents = null;
    
                Tmds.DBus.ObjectPath objectPath = new Tmds.DBus.ObjectPath("/klipper");
                string service = "org.kde.klipper";
    
                using (Tmds.DBus.Connection connection = new Tmds.DBus.Connection(Tmds.DBus.Address.Session))
                {
                    await connection.ConnectAsync();
    
                    Klipper.DBus.IKlipper klipper = connection.CreateProxy(service, objectPath);
    
                    clipboardContents = await klipper.getClipboardContentsAsync();
                } // End Using connection 
    
                return clipboardContents;
            } // End Task GetClipboardContentsAsync 
    
    
        } // End Class LinuxClipBoardAPI 
    
    
    } // End Namespace TestMe
    

    AsyncEx is required in the abstract class for synchronizing in the get/set property. AsyncEx not required for the actual clipboard handling, as long as you don't want to utilize the get/set clipboard contents in a synchronous context.

提交回复
热议问题