如何在C#中备份和恢复系统剪贴板?

我会尽我所能详细解释我想要达到的目标。

我正在使用C#与IntPtr窗口句柄执行从我自己的C#应用​​程序的外部应用程序的CTRL-C复制操作。 我必须这样做,因为没有办法直接使用GET_TEXT访问文本。 然后我在我的应用程序中使用该副本的文本内容。 这里的问题是,我现在已经覆盖了剪贴板。

我希望能够做的是:

  1. 备份可能由我自己以外的任何应用程序设置的剪贴板的原始内容。
  2. 然后执行复制并将值存储到我的应用程序中。
  3. 然后恢复剪贴板的原始内容,以便用户仍然可以访问他/她的原始剪贴板数据。

这是我迄今为止所尝试的代码:

private void GetClipboardText() { text = ""; IDataObject backupClipboad = Clipboard.GetDataObject(); KeyboardInput input = new KeyboardInput(this); input.Copy(dialogHandle); // Performs a CTRL-C (copy) operation IDataObject clipboard = Clipboard.GetDataObject(); if (clipboard.GetDataPresent(DataFormats.Text)) { // Retrieves the text from the clipboard text = clipboard.GetData(DataFormats.Text) as string; } if (backupClipboad != null) { Clipboard.SetDataObject(backupClipboad, true); // throws exception } } 

我正在使用System.Windows.Clipboard而不是System.Windows.Forms.Clipboard。 原因是当我执行CTRL-C时,System.Windows.Forms中的Clipboard类没有返回任何数据,但是系统剪贴板没有。

我看了一些像OpenClipboard,EmptyClipboard和CloseClipboard的低级别的用户调用,希望他们能帮助我做到这一点,但到目前为止,我仍然在尝试恢复时遇到COMexception。

我想也许这与OpenClipboard参数,这是期望一个IntPtr窗口句柄的应用程序,想要控制剪贴板。 由于我提到我的应用程序没有GUI,这是一个挑战。 我不知道该怎么通过这里。 也许有人可以对此有所了解?

我是否正确使用剪贴板类? 有没有一种清晰的方式来获得没有GUI的应用程序的IntPtr窗口句柄? 有谁知道更好的方法来备份和恢复系统剪贴板?

尝试这样做是愚蠢的。 您不能忠实地将剪贴板恢复到之前的状态。 可能有数十种使用“延迟呈现”呈现的未呈现数据格式,如果您尝试呈现所有数据格式,则会导致源应用程序耗尽资源。 就像走进一家餐厅,说“给我一个东西”。

假设用户在Excel中select了500行×100列,并将其复制到剪贴板。 Excel“宣传”它可以以大约25种不同的格式生成这些数据,包括位图。 将其粘贴为位图后,您将强制Excel将其呈现为位图。 这是50000个单元格,并将是一个约10,000 x 15,000像素的位图。 而且你期望用户等待,Excel和其他24种格式一起咳嗽吗? 不可行。

此外,您将触发WM_DrawClipboard事件,这将影响其他剪贴板查看器。

放弃。

您可以将剪贴板的内容保存在字典中,然后恢复:

 public IDictionary<string, object> GetClipboardData() { var dict = new Dictionary<string, object>(); var dataObject = Clipboard.GetDataObject(); foreach(var format in dataObject.GetFormats()) { dict.Add(format, dataObject.GetData(format)); } return dict; } public void SetClipboardData(IDictionary<string, object> dict) { var dataObject = Clipboard.GetDataObject(); foreach(var kvp in dict) { dataObject.SetData(kvp.Key, kvp.Value); } } ... var backup = GetClipboardData(); // Do something with the clipboard... ... SetClipboardData(backup);