> 首先我表达一下个人对迅雷的强烈不满
> 迅雷在接管剪贴板之后会持续扫描剪贴板,导致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); 经常遇见这个问题
这也就是为什么文章开头我怒怼迅雷。
因为迅雷的持续读取,我们不得不思考用另外一种方式来复制到剪贴板。
没错!
它就是 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();
}