【无法打开剪贴板】C#-Clipboard剪贴板粘贴文字SetText报错

> 首先我表达一下个人对迅雷的强烈不满
> 迅雷在接管剪贴板之后会持续扫描剪贴板,导致C#中传统的复制方法失效。

## 剪贴板的正常使用

### 传统方法

CSharp 内置 Clipboard 类封装了一系列操作剪贴板的方法
WPF: System.Windows.Clipboard
Winform: System.Windows.Forms.Clipboard
两者的操作方法类似
另外,你还可以在引用 VisualBasic 库后在 C# 中调用 VB 来复制
当然,这是后话了。

### WPF - System.Windows.Clipboard

MSDN 上的示例:

``` C#
string textData = "I want to put this string on the clipboard.";
Clipboard.SetData(DataFormats.Text, (Object)textData);
方法 功能
Clear() 从系统剪贴板中清除任何数据。
ContainsAudio() 查询剪贴板上是否存在 WaveAudio 数据格式的数据。
ContainsData(String) 查询剪贴板上是否存在指定数据格式的数据。
ContainsFileDropList() 查询剪贴板上是否存在 FileDrop 数据格式的数据。
ContainsImage() 查询剪贴板上是否存在 Bitmap 数据格式的数据。
ContainsText() 查询剪贴板上是否存在 UnicodeText 格式的数据。
ContainsText(TextDataFormat) 查询剪贴板上是否存在文本数据格式的数据。
Flush() 永久地添加 Clipboard 上的数据,使其在数据的原始应用程序关闭后可用。
GetAudioStream() 返回 WaveAudio 数据格式的剪贴板数据流。
GetData(String) 从剪贴板检索指定格式的数据。
GetDataObject() 返回表示剪贴板全部内容的数据对象。
GetFileDropList() 返回一个字符串集合,其中包含剪贴板上提供的拖放文件的列表。
GetImage() 从剪贴板返回一个 BitmapSource 对象,其中包含 Bitmap 格式的数据。
GetText() 返回一个包含剪贴板上 UnicodeText 数据的字符串。
GetText(TextDataFormat) 返回一个包含剪贴板上文本数据的字符串。
IsCurrent(IDataObject) 比较指定的数据对象与剪贴板的内容。
SetAudio(Byte[]) 将音频数据(WaveAudio 数据格式)存储在剪贴板上。 音频数据指定为字节数组。
SetAudio(Stream) 将音频数据(WaveAudio 数据格式)存储在剪贴板上。 音频数据指定为流。
SetData(String, Object) 以指定格式在剪贴板上存储指定数据。
SetDataObject(Object) 将指定的非永久性数据对象放置在系统剪贴板上。
SetDataObject(Object, Boolean) 将指定的数据对象置于系统剪贴板中,并接受一个布尔参数,该参数指示应用程序退出时是否将数据对象保留在剪贴板中。
SetFileDropList(StringCollection) 将 FileDrop 数据存储在剪贴板上。 拖放文件列表指定为字符串集合。
SetImage(BitmapSource) 将 Bitmap 数据存储在剪贴板上。 图像数据指定为 BitmapSource。
SetText(String) 将 UnicodeText 数据存储在剪贴板上。
SetText(String, TextDataFormat) 以指定的文本数据格式在剪贴板上存储文本数据。 将要存储的 UnicodeText 数据指定为一个字符串。

最常见的问题

在大多数人的电脑上执行 Clipboard.SetText(xxx); 经常遇见这个问题

【无法打开剪贴板】C#-Clipboard剪贴板粘贴文字SetText报错
这也就是为什么文章开头我怒怼迅雷。
因为迅雷的持续读取,我们不得不思考用另外一种方式来复制到剪贴板。
没错!
它就是 WinAPI 。

用 WinAPI 来复制, 绕过迅雷

下面的代码我将会贴出下载链接在文章末尾,请查收

首先,我们先引用一下需要用到的库:

using System;
using System.Runtime.InteropServices;

再然后,添加 User32.dll 中的方法:

[DllImport("User32")]
public static extern bool OpenClipboard(IntPtr hWndNewOwner);

[DllImport("User32")]
public static extern bool CloseClipboard();

[DllImport("User32")]
public static extern bool EmptyClipboard();

[DllImport("User32")]
public static extern bool IsClipboardFormatAvailable(int format);

[DllImport("User32")]
public static extern IntPtr GetClipboardData(int uFormat);

[DllImport("User32", CharSet = CharSet.Unicode)]
public static extern IntPtr SetClipboardData(int uFormat, IntPtr hMem);

复制的方法:

/// <summary>
/// 向剪贴板中添加文本
/// </summary>
/// <param name="text">文本</param>
public static void SetText(string text)
{
    if (!OpenClipboard(IntPtr.Zero))
    {
        SetText(text);
        return;
    }
    EmptyClipboard();
    SetClipboardData(13, Marshal.StringToHGlobalUni(text));
    CloseClipboard();
}

下载的地址:http://source.catrol.cn/Clipboard.cs

上一篇:clipboard.js的使用


下一篇:vue 实现点击复制指定内容到粘贴板