剪切板是Windows系统提供的功能,从我最早接触到的Windows 3.2版本开始,就一直带着了。以前使用C++的时候,是直接使用Windows API对其进行操作的,到了.NET下,在WinForm中也有一个对剪切板的封装类,即System.Windows.Forms.Clipboard,这个类其实是通过COM组件间接地使用剪切板的,我个人觉得COM是一个设计非常糟糕的东西,难懂坑多还不可移植,但微软现存的大量代码又是基于COM的,所以又无法彻底舍弃,关于不可移植这个并不难理解,前面说了,剪切板是Windows提供的功能,你在Linux下,或者在MacOS下,尽管有类似的功能,但跟Windows的肯定不同,所以最新的.NET Core中是不能使用剪切板功能的。

往剪切板里存取字符串

字符串是最最常用的数据对象了,我们就往剪切板里写一个字符串吧,我总结了一下,见下表:

方法1 Clipboard.SetText(str);  很可能有问题
方法2 Clipboard.SetData(DataFormats.Text,str);  很可能有问题
方法3 Clipboard.SetDataObject(str);  大多数时候没问题

嗯?怎么这么不确定?确实如此,这是我进行了大量试验的结果,且程序在调试和非调试中还有不同的表现,可能出现的异常有以下两个:

(异常1:COMException)

(异常2:ExternalException)

两个异常都没有进一步的提示信息,异常的原因很类似,就是剪切板访问不了,而我使用方法3的时候,在非调试状态下还没发现过什么问题。我实在找不到进一步的规律了,先这样用吧。

那么如何从剪切板获取字符串呢?对应的,有两种方法:

方法1 string str = (string)Clipboard.GetData(DataFormats.Text) 很可能有问题
方法2 string str = Clipboard.GetText(); 大多数时候没问题

具体原因我同样不太清楚,这似乎是微软留下的一个bug,SO上有个讨论,可以去看看:StackOverflow

另外还有两点需要注意:

  1. 方法3这种往剪切板里写文本内容的方式,在这个程序结束之后,剪切板内容将会失效,要使得程序结束后剪切板内容继续有效的话,得使用Clipboard.SetDataObject(str, true);这个方法,第二个参数true表示让剪切板内容在程序结束后继续有效,但我发现加上这个参数之后,增加了出现异常的可能性。
  2. 必须在给程序的入口函数(通常是Main函数)加上STAThreadAttribute这个注解,否则对剪切板的访问会报错:在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。

往剪切板里存取自定义数据

C#的对象的数据结构并不能为剪切板所理解,所以你要把你自定义的数据放到剪切板去的话要把它序列化,在实际操作中,是要你提供一个“可序列化”的对象,下面是个简单的例子:

[Serializable]
public class User {
public int age { get; set; }
public string name { get; set; }
} class Program {
[STAThread]
static void Main(string[] args) {
User userIn = new User();
userIn.name = "Jack";
userIn.age = ;
Clipboard.SetData("mydata", userIn);
User userOut = (User)Clipboard.GetData("mydata");
Console.WriteLine(userOut.name +" | " + userOut.age);
}
}

注意User这个类前面的Serializable注解,如果没有这个注解,是没法成功将对象写入剪切板的。如果数据比较复杂,可以考虑把数据自行序列化到一个Stream对象去,再把Stream对象写入剪切板,获取的时候对Stream对象自行反序列化,还原数据。例子就不写了。

最后要注意的一点是由于这里的数据类型是“mydata”,你也可以指定别的名字,这种类型数据只有你自己的程序能读懂,也就是说,你是不能打开记事本或者Photoshop,直接把你这个User对象贴上去的。

C#操作剪切板(Clipboard)的更多相关文章

  1. C# 使用WinApi操作剪切板Clipboard

    前言: 最近正好写一个程序,需要操作剪切板 功能很简单,只需要从剪切板内读取字符串,然后清空剪切板,然后再把字符串导入剪切板 我想当然的使用我最拿手的C#来完成这项工作,原因无他,因为.Net框架封装 ...

  2. Javascript操作剪切板数据(支持IE、Chrome、360、搜狗),亲测!

    clipboarddata只能在IE浏览器中使用,在chrome下会提示对象未定义!以下的方法支持IE.Chrome.360.搜狗等浏览器,其它浏览器还未验证. <!DOCTYPE html&g ...

  3. c#操作剪切板

    C#定义了一个类System.Windows.Forms.Clipboard来简化剪切板操作,这个类有一个静态方法,主要有: Clear 清除剪切板中的所有数据: ContainsData,Conta ...

  4. 对c#剪切板Clipboard占用的问题一点解决方法

    以前在百度写的文档,转移到此处 前几天做一个程序,其中有一个剪切板的操作,具体代码: Clipboard.SetText(“ABC”); 来完成一个复制字符串的操作. 自己调试通过,完全正常,然后就交 ...

  5. 在Java中调用与系统有关的剪切板Clipboard

    java从1.5版开始已经能与系统的剪切板很好的交互了. 如果可以在程序中直接调用系统的剪切板来保存“复制”的对象内容,那可以说的比之前的想法好很多. 下面是一个对java.io.File对象进行co ...

  6. VBS操作剪切板

    '设置剪切板的内容 Dim Form, TextBox Set Form = CreateObject("Forms.Form.1") Set TextBox = Form.Con ...

  7. python 操作剪切板

    python3 在使用网上找到的一些使用剪切板的片段时发现存在写入剪切板后乱码的情况, 研究后发现python3不能使用SetClipboardData方法, 要使用SetClipboardText ...

  8. 【转载】VC操作剪切板

    1.在剪切板上放置数据 if(OpenClipboard())    //打开剪切板{    EmptyClipboard(); //清空剪切板    CString str;       //从控件 ...

  9. 使用ZeroClipboard操作剪切板

    一.ZeroClipboard下载地址 点击下载 二.添加js引用 <script src="../Assets/js/jquery-1.8.3.min.js">< ...

随机推荐

  1. 关于Java泛型"擦除"的一点思考

    头次写博客,想说的东西不难,关于泛型的疑问,是前一阵在学习jackson中遇到的. 下面就把我所想到的.遇到的,分享出来. 泛型是JDK1.5后的一个特性,是一个参数类型的应用,可以将这个参数声明在类 ...

  2. 常用的HTML富文本编译器UEditor、CKEditor、TinyMCE、HTMLArea、eWebEditor、KindEditor简介

    1.UEditor UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于BSD协议,允许自由使用和修改代码... 主要特点: 轻量级: ...

  3. React Native在特赞的应用与实践

    基于React技术栈构建开发前端项目,并使用React Native开发特赞移动APP 目前正在使用Node.js开发和维护特赞服务网关,希望Node.js能够在更轻量级的微服务架构中发挥重要作用 课 ...

  4. 使用wordpress搭建自己的独立博客

    最近想要搭建自己的私人博客, 各种百度,完整的搭建步骤如下! 首先得要有自己的vps或者云主机,我这里是自己的云主机,有自己的域名(我这边目前没有买域名)! 搭建步骤! 1,安装lnmp(linux+ ...

  5. Celery beat实现定时/轮询任务

    Celery定时任务 配置 启用Celery的定时任务需要设置CELERYBEAT_SCHEDULE .  Celery的定时任务都由celery beat来进行调度.celery beat默认按照s ...

  6. HashMap浅入理解

    HashMap不能保证元素的顺序,HashMap能够将键设为null,也可以将值设为null,与之对应的是Hashtable,(注意大小写:不是HashTable),Hashtable不能将键和值设为 ...

  7. ranker_worker.go

    package         outputDocs, numDocs := engine.rankers[shard].Rank(request.docs, request.options, req ...

  8. CyclicBarrier简介

    CyclicBarrier简介 CyclicBarrier和CountDownLatch不同,是当await的数量达到了设定的数量之后,才继续往下执行 CyclicBarrier数的是调用了Cycli ...

  9. BZOJ_1369_[Baltic2003]Gem_树形DP

    BZOJ_1369_[Baltic2003]Gem_树形DP Description 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值, ...

  10. h5仿微信聊天(高仿版)、微信聊天表情|对话框|编辑器

    之前做过一版h5微信聊天移动端,这段时间闲来无事就整理了下之前项目,又重新在原先的那版基础上升级了下,如是就有了现在的h5仿微信聊天高仿版,新增了微聊.通讯录.探索.我四个模块 左右触摸滑屏切换,聊天 ...