.Net Core - 复制到剪贴板?

2024-02-05

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

看来Clipboard https://msdn.microsoft.com/en-us/library/system.windows.clipboard(v=vs.110).aspx缺少类,并且 P/Invoking 不是 Windows 之外的选项。

Edit: Unfortunately until now there's been a discrepancy between what my question said and what people heard when they read the question. Based on the comments and answers two things are clear. First, very few care whether the truest kind of "ivory tower" platform agnosticism exists or not. Second, when people post code examples showing how you use the clipboard on different platforms then the technically correct answer ("no, it's not possible https://stackoverflow.com/a/49459767/3063273") is confusing. So I have struck the parenthetical clause.


我的这个项目(https://github.com/SimonCropp/TextCopy https://github.com/SimonCropp/TextCopy)使用 PInvoke 和命令行调用的混合方法。目前它支持

  • 装有 .NET Framework 4.6.1 及更高版本的 Windows
  • 带有 .NET Core 2.0 及更高版本的 Windows
  • 装有 Mono 5.0 及更高版本的 Windows
  • 带有 .NET Core 2.0 及更高版本的 OSX
  • OSX 与 Mono 5.20.1 及更高版本
  • 带有 .NET Core 2.0 及更高版本的 Linux
  • 采用 Mono 5.20.1 及更高版本的 Linux

Usage:

Install-Package TextCopy

TextCopy.ClipboardService.SetText("Text to place in clipboard");

或者直接使用实际的代码

Windows

https://github.com/CopyText/TextCopy/blob/master/src/TextCopy/WindowsClipboard.cs https://github.com/CopyText/TextCopy/blob/master/src/TextCopy/WindowsClipboard.cs

static class WindowsClipboard
{
    public static void SetText(string text)
    {
        OpenClipboard();

        EmptyClipboard();
        IntPtr hGlobal = default;
        try
        {
            var bytes = (text.Length + 1) * 2;
            hGlobal = Marshal.AllocHGlobal(bytes);

            if (hGlobal == default)
            {
                ThrowWin32();
            }

            var target = GlobalLock(hGlobal);

            if (target == default)
            {
                ThrowWin32();
            }

            try
            {
                Marshal.Copy(text.ToCharArray(), 0, target, text.Length);
            }
            finally
            {
                GlobalUnlock(target);
            }

            if (SetClipboardData(cfUnicodeText, hGlobal) == default)
            {
                ThrowWin32();
            }

            hGlobal = default;
        }
        finally
        {
            if (hGlobal != default)
            {
                Marshal.FreeHGlobal(hGlobal);
            }

            CloseClipboard();
        }
    }

    public static void OpenClipboard()
    {
        var num = 10;
        while (true)
        {
            if (OpenClipboard(default))
            {
                break;
            }

            if (--num == 0)
            {
                ThrowWin32();
            }

            Thread.Sleep(100);
        }
    }

    const uint cfUnicodeText = 13;

    static void ThrowWin32()
    {
        throw new Win32Exception(Marshal.GetLastWin32Error());
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr GlobalLock(IntPtr hMem);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GlobalUnlock(IntPtr hMem);

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool OpenClipboard(IntPtr hWndNewOwner);

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CloseClipboard();

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr SetClipboardData(uint uFormat, IntPtr data);

    [DllImport("user32.dll")]
    static extern bool EmptyClipboard();
}

macOS

https://github.com/CopyText/TextCopy/blob/master/src/TextCopy/OsxClipboard.cs https://github.com/CopyText/TextCopy/blob/master/src/TextCopy/OsxClipboard.cs

static class OsxClipboard
{
    public static void SetText(string text)
    {
        var nsString = objc_getClass("NSString");
        IntPtr str = default;
        IntPtr dataType = default;
        try
        {
            str = objc_msgSend(objc_msgSend(nsString, sel_registerName("alloc")), sel_registerName("initWithUTF8String:"), text);
            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);
        }
        finally
        {
            if (str != default)
            {
                objc_msgSend(str, sel_registerName("release"));
            }

            if (dataType != default)
            {
                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";
}

Linux

https://github.com/CopyText/TextCopy/blob/master/src/TextCopy/LinuxClipboard_2.1.cs https://github.com/CopyText/TextCopy/blob/master/src/TextCopy/LinuxClipboard_2.1.cs

static class LinuxClipboard
{
    public static void SetText(string text)
    {
        var tempFileName = Path.GetTempFileName();
        File.WriteAllText(tempFileName, text);
        try
        {
            BashRunner.Run($"cat {tempFileName} | xclip");
        }
        finally
        {
            File.Delete(tempFileName);
        }
    }

    public static string GetText()
    {
        var tempFileName = Path.GetTempFileName();
        try
        {
            BashRunner.Run($"xclip -o > {tempFileName}");
            return File.ReadAllText(tempFileName);
        }
        finally
        {
            File.Delete(tempFileName);
        }
    }
}

static class BashRunner
{
    public static string Run(string commandLine)
    {
        var errorBuilder = new StringBuilder();
        var outputBuilder = new StringBuilder();
        var arguments = $"-c \"{commandLine}\"";
        using (var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "bash",
                Arguments = arguments,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = false,
            }
        })
        {
            process.Start();
            process.OutputDataReceived += (sender, args) => { outputBuilder.AppendLine(args.Data); };
            process.BeginOutputReadLine();
            process.ErrorDataReceived += (sender, args) => { errorBuilder.AppendLine(args.Data); };
            process.BeginErrorReadLine();
            if (!process.WaitForExit(500))
            {
                var timeoutError = $@"Process timed out. Command line: bash {arguments}.
Output: {outputBuilder}
Error: {errorBuilder}";
                throw new Exception(timeoutError);
            }
            if (process.ExitCode == 0)
            {
                return outputBuilder.ToString();
            }

            var error = $@"Could not execute process. Command line: bash {arguments}.
Output: {outputBuilder}
Error: {errorBuilder}";
            throw new Exception(error);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.Net Core - 复制到剪贴板? 的相关文章

  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现

随机推荐

  • 如何使用 Python 获取触发我的 Azure 函数的 inputBlob 的名称

    我有一个天蓝色的函数 它是由放入 blob 存储的文件触发的 我想知道如何 如果可能 获取触发该函数的 blob 文件 的名称 我尝试这样做 fileObject os environ inputBlob message Python sc
  • 尝试启动 Atom/Nuclide 时未找到流

    我正在研究react native我正在使用的应用程序AtomIDE 我在打开时遇到错误Atom 我安装了babel cli and babel preset flow使用 npm 命令 npm install save dev babel
  • 将 MS Access 表单和类/模块递归导出到文本文件?

    我在一个古老的留言板上发现了一些代码 它很好地从类 模块和表单中导出了所有 VBA 代码 见下文 Option Explicit Option Compare Database Function SaveToFile Save the co
  • Java 8 流式添加两个或多个列表中的值

    我试图进入 Java 8 并了解流和 lambda 来解决各种问题 但陷入了这个特定的问题 我通常使用 forEach 并将值存储在 Map 中来解决 您将如何编写代码来使用 Java 8 中的新功能获取预期列表 List
  • 具有选择条件的 pandas 数据框中的高效最大选择

    我有一个带有列的 pandas 数据框 除其他外 user id and start time 我想高效且易读地找到与每个用户的最大值关联的所有行start time 例如 如果这是我的数据 user id start time A B C
  • 批量传输和 Android USB API

    我有一个程序 我尝试通过 USB 将我的 Android 设备连接到网络摄像头 我在一些事情上遇到了麻烦 即正确传输数据 我尝试过使用bulkTransfer 但似乎无法识别它的使用情况 我一直在尝试寻找可能对我有帮助的例子 例如here
  • 使用 Scala 生成代码

    在 Scala 中使用 SBT 工具链时 是否可以编写一个任务来读取项目源代码的特殊部分以在编译时生成 scala 代码 有什么想法甚至文章 教程吗 我正在寻找与 Template Haskell 非常相似的东西 环树者 scala htt
  • Laravel Lighthouse 中的身份验证

    在我的 graphql API 中 我必须通过两个不同的因素来授权对字段的请求 用户是否有权访问数据或者数据是否属于用户 例如 用户应该能够看到自己的用户数据 并且所有具有管理员权限的用户也应该能够看到这些数据 我想保护这些字段 以便具有不
  • RedisTemplate过期不起作用

    我正在尝试测试 RedisTemplate 中的过期方法 例如 我将会话存储在 redis 中 然后尝试检索会话并检查值是否相同 对于过期会话 我使用 redisTemplate 的 expire 方法 对于获取过期会话 我使用 getEx
  • NuGet System.Drawing.Common .NET 6 CA1416 此调用站点可在所有平台上访问。 “Image.FromStream(Stream)”仅支持:“windows”

    升级 NuGetSystem Drawing Common到 6 0 0 会导致以下错误 CA1416 此调用站点可在所有平台上访问 仅在 Windows 上支持 Image FromStream Stream https www nuge
  • 无法将整数类型转换为 uuid

    我试着跑python3 manage py migrate 但我得到了这个error File Library Frameworks Python framework Versions 3 8 lib python3 8 site pack
  • 特定于页面的 CSS 规则 - 将它们放在哪里?

    通常 当我设计网站时 我需要将特定样式应用于页面上的特定元素 并且我绝对确定它只会应用于该页面上的该元素 例如绝对定位的按钮 或者其他的东西 我不想诉诸内联样式 因为我倾向于同意样式与标记分开的理念 所以我发现自己在内部争论将样式定义放在哪
  • Pandas 重新映射到列中的范围

    我有一个带有 id s 列的 DataFrame 可以包含重复项 gt gt gt df user id head Out 3 0 2134 1 1234 2 4323 3 25434 4 1234 Name user id dtype i
  • Roxygen2 - 如何 @export 引用类生成器?

    例如 假设我有以下包称为Test我想导出课程A In R Test R docType package import methods exportClass A A lt setRefClass A methods list foo ide
  • ASP.NET 内存泄漏 - OracleCommand 对象

    我有内存泄漏 我很难找出问题出在哪里 ASP NET 进程时常会增加到 1GB 我已按照本页 http humblecoder co uk tag windbg 上的说明进行操作 并且 gcroot 命令返回以下内容 最后 x 行 我查看了
  • 将字符串格式化为标题大小写

    如何将字符串格式化为标题大小写 http www grammar monster com lessons capital letters title case htm 下面是一个在 C 中执行此操作的简单静态方法 public static
  • 如何在映射器(Hadoop)中使用MATLAB代码?

    我有一个处理图像的 matlab 代码 我想创建一个使用该代码的 Hadoop 映射器 我遇到了以下解决方案 但不确定哪一个最好 因为对我来说 在 hadoop 中的每个从属节点上安装 matlab 编译器运行时非常困难 手动将该 matl
  • SendKeys Ctrl + C 到外部应用程序(文本到剪贴板)

    我有一个应用程序作为托盘图标位于系统托盘中 我已经注册了一个热键 按下该热键将捕获任何应用程序中的当前文本选择 甚至在 Web 浏览器中也是如此 我的方法是发送组合键 Ctrl C 来复制文本 然后访问剪贴板并在我自己的应用程序中使用该文本
  • 如何使用 FlowLayout 确定 UICollectionView 的高度

    我有一个UICollectionView与UICollectionViewFlowLayout 我想计算它的内容大小 返回intrinsicContentSize通过自动布局调整其高度所需的 问题是 即使我对所有单元格都有固定且相等的高度
  • .Net Core - 复制到剪贴板?

    Is it possible to copy something to the clipboard using Net Core in a platform agnostic way 看来Clipboard https msdn micro