Как создать резервную копию и восстановить системный буфер обмена в C #?

Я сделаю все возможное, чтобы подробно объяснить, чего я пытаюсь достичь.

Я использую C # с дескрипторами windows IntPtr для выполнения операции копирования CTRL-C во внешнем приложении из моего собственного приложения 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, class Clipboard из System.Windows.Forms не возвращал никаких данных, но сделал системный буфер обмена.

Я заглянул в некоторые из нижестоящих вызовов user32, таких как OpenClipboard, EmptyClipboard и CloseClipboard, надеясь, что они помогут мне это сделать, но до сих пор я продолжаю получать исключения COM при попытке восстановить.

Я подумал, что, возможно, это связано с параметром OpenClipboard, который ожидает дескриптор windows IntPtr приложения, который хочет взять под контроль буфер обмена. Поскольку я упоминал, что мое приложение не имеет графического интерфейса, это вызов. Я не был уверен, что мне нужно здесь пройти. Может быть, кто-то может пролить свет на это?

Я неправильно использую class Clipboard? Есть ли четкий способ получить дескриптор windows IntPtr приложения без GUI? Кто-нибудь знает лучший способ резервного копирования и восстановления системного буфера обмена?

Глупо пытаться это сделать. Вы не можете точно восстановить буфер обмена до его предыдущего состояния. Там могут быть десятки нераспределенных форматов данных, которые присутствуют с использованием «отложенного рендеринга», и если вы попытаетесь отобразить их все, это приведет к тому, что исходное приложение закончится из ресурсов. Это как идти в resturaunt и говорить «дайте мне одно из всего».

Предположим, что пользователь выбрал 500 строк по 100 столбцов в Excel и скопировал их в буфер обмена. Excel «рекламирует», что он может создавать эти данные примерно в 25 разных форматах, включая Bitmap. После того, как вы вставляете его в виде растрового изображения, вы вынуждаете Excel отображать его как bitmap. Это 50000 ячеек, и это будет bitmap размером около 10 000 х 15 000 пикселей. И вы ожидаете, что пользователь будет ждать, пока Excel кашляет, вместе с 24 другими форматами? Невозможно.

Кроме того, вы будете запускать события WM_DrawClipboard, что повлияет на других зрителей буфера обмена.

Сдаваться.

Вы можете сохранить содержимое буфера обмена в словаре и впоследствии восстановить его:

 public IDictionary GetClipboardData() { var dict = new Dictionary(); var dataObject = Clipboard.GetDataObject(); foreach(var format in dataObject.GetFormats()) { dict.Add(format, dataObject.GetData(format)); } return dict; } public void SetClipboardData(IDictionary 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); 
Давайте будем гением компьютера.