C # Резервное копирование и восстановление буфера обмена - PullRequest
7 голосов
/ 07 июня 2011

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

Это мой код:

IDataObject temp = Clipboard.GetDataObject();

//Some stuff that change Cliboard here
Clipboard.SetText("Hello");
//Some stuff that change Cliboard here

Clipboard.SetDataObject(temp);

Но если я копирую текст и запускаю этот код, я ничего не получаю в блокноте.

ПРИМЕЧАНИЕ. Я не могу использовать буфер обмена. Содержит, потому что я хочу сохранить буфер обмена ТОЧНО, как это было раньше, даже если пользователь скопировал файл.

Ответы [ 5 ]

3 голосов
/ 07 июня 2011

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

Читать здесь: http://msdn.microsoft.com/en-us/library/system.windows.forms.idataobject.aspx

Вы бы сделали что-то вроде (псевдокод)

//Backup
var lBackup = new Dictionary<string, object>();
var lDataObject = Clipboard.GetDataObject();
var lFormats = lDataObject.GetFormats(false);
foreach(var lFormat in lFormats)
{
  lBackup.Add(lFormat, lDataObject.GetData(lFormat, false));
}

//Set test data
Clipboard.SetText("asd");

//Would be interesting to check the contents of lDataObject here

//Restore data
foreach(var lFormat in lFormats)
{
  lDataObject.SetData(lBackup[lFormat]);
}
//This might be unnecessary
Clipboard.SetDataObject(lDataObject);
1 голос
/ 07 июня 2011

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

Предполагается, что это приложение Win Form.(хотя не знаю, как это работает в wpf) Вы можете использовать одну из других перегруженных версий Clipboard.SetDataObject

public static void SetDataObject(object data, bool copy) 

, которая сохраняет данные даже после выхода из приложения.

ex:в вашем случае после удаления текстового содержимого вы могли бы позвонить Clipboard.SetDataObject(iDataObject, true);

РЕДАКТИРОВАТЬ: 2

Я мог бы шаг источника через Clipboard.cs .NET Frameword 4 / VS 2010Загрузите .NET Framework 4 отсюда http://referencesource.microsoft.com/netframework.aspx. Выполните следующие шаги, и если он запрашивает источник (Clipboard.cs), он будет находиться в подкаталоге Source установочного каталога.

РЕДАКТИРОВАТЬ: 1

Не уверен, почему тот же код не работает.Не может быть проблемой безопасности / разрешения, так как код не выдает исключение, как вы говорите.

Существует другой подход - переход на исходный код в код Framework - Clipboard.cs На основе версии VS и .NET Framework этоможет отличаться (я не смог получить пошаговую работу с исходным кодом для .NET 4, так как информация о том, что символы с поддержкой исходного кода еще не выпущены).Я пытаюсь попытать счастья, загрузив его вручную с здесь (.NET Version 4)

Если вы используете VS 2008 и более старую версию .NET, то следующие шаги должны работать для вас.

Source Symbol Setting

General Debugging Settings

Подробнее здесь .Для .NET Framework 4 - здесь

0 голосов
/ 27 февраля 2019

Я скомпилировал этот код, и он, кажется, работает для меня. Я настаиваю через преобразование в и из JSON. (Примечание. Пары не подойдут, поэтому адаптируйтесь, если вам это нужно)

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace Clipboard
{
    class Program
    {
        static void Main(string[] args)
        {                                    
            Execute(() =>
            {
                var backup = Backup();
                System.Windows.Forms.Clipboard.SetText("text"); //just to change clipboard
                Restore(backup);
            });                
        }

        private static void Execute(Action action)
        {
            var thread = new Thread(() => action());
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();
        }

        private static List<ClipboardItem> Backup()
        {
            var backup = new List<ClipboardItem>();
            var data = System.Windows.Forms.Clipboard.GetDataObject();
            System.Windows.Forms.Clipboard.SetDataObject(data, copy: true); //This seems to be needed to be able to serialize data later.
            data = System.Windows.Forms.Clipboard.GetDataObject();
            var formats = data.GetFormats(false).ToList();
            formats.ForEach(f =>
            {
                if (data.GetData(f, false) != null && !(data.GetData(f, false) is Stream))
                {                    
                    backup.Add(new ClipboardItem()
                    {
                        Format = f,
                        ObjectType = data.GetData(f, false).GetType(),
                        ObjectJson = JsonConvert.SerializeObject(data.GetData(f, false))
                    });
                }                
            });            
            return backup;
        }

        private static void Restore(List<ClipboardItem> backup)
        {
            var data = new System.Windows.Forms.DataObject();
            backup.ForEach(item =>
            {               
                data.SetData(item.Format, JsonConvert.DeserializeObject(item.ObjectJson, item.ObjectType));
            });
            System.Windows.Forms.Clipboard.SetDataObject(data, copy: true);
        }
    }    

    public class ClipboardItem
    {
        public string Format { get; set; }
        public Type ObjectType { get; set; }
        public string ObjectJson { get; set; }
    }
}
0 голосов
/ 20 октября 2014

У меня был успех с этим.

... в определенной степени.

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

Затем я попытался сделать то же самое для (как и предполагал Крис Торнтон) предварительного листа Excel с двумя тысячами данных ячеек, а также с двумя наборами данных на графике, лежащем на одном листе.

Я обнаружил, что данные копируются и восстанавливаются без проблем. В этом случае он разрешает использование двухсеточного графа с копией рабочего листа.

Если у кого-то из вас возникла проблема с копированием и восстановлением растровых изображений, позвольте мне предложить то, что сработало для меня: при попытке восстановить буфер обмена переберите список форматов в обратном порядке и установите каждый объект данных таким образом. (т.е. кажется, что буфер обмена должен быть установлен в обратном порядке, в котором он был скопирован)

Что касается случая гигантского рабочего листа Excel и сопровождающего графика, я также наткнулся на другой камень преткновения: я не смог успешно скопировать объект данных, формат которого был «Файл метаданных». Это может быть причиной того, что в этом случае копирование / восстановление не работает.

Я понял это примерно две недели назад и внес на обсуждение более насущные вопросы.

Я хотел показать это, чтобы кто-то еще пытался сделать то же самое, что, кажется, можно сделать. (в информатике можно делать все, что угодно.)

0 голосов
/ 11 июня 2011

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

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

Кроме того, я подозреваю, что ваша мотивация для резервного копирования / восстановления буфера обмена заключается в том, что вы хотите использовать его в качестве опоры для перемещения данных без ведома или согласия пользователя. Пожалуйста, прочитайте: http://www.clipboardextender.com/developing-clipboard-aware-programs-for-windows/common-general-clipboard-mistakes а также http://www.flounder.com/badprogram.htm#clipboard

Наконец, пожалуйста, прочитайте и поймите эту цитату:

«Программы не должны передавать данные в наш буфер обмена без явного указания от пользователя». - Чарльз Петцольд, Программирование Windows 3.1, Microsoft Press, 1992

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...