首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 剪貼板完整備份恢復:IDataObject 序列化方案解決自定義格式丟失

     編輯:程式設計綜合問答

問題

Clipboard.GetText() 等僅支援標準格式,無法處理用戶自定義格式 (如 Excel 範圍、VS 代碼片段、專有業務對象)。逐項枚舉 GetDataPresent 仍會遺漏未知格式。

解決方案:序列化整個 IDataObject

利用 IDataObject 實現 ISerializable,將完整剪貼板內容二進制序列化到內存流,恢復時反序列化並 Clipboard.SetDataObject。

核心代碼


using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;

public static class ClipboardEx {
    public static byte[] Backup() {
        IDataObject data = Clipboard.GetDataObject();
        if (data == null) return null;
        using (var ms = new MemoryStream()) {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, data);
            return ms.ToArray();
        }
    }

    public static void Restore(byte[] backup) {
        if (backup == null || backup.Length == 0) return;
        using (var ms = new MemoryStream(backup)) {
            var formatter = new BinaryFormatter();
            IDataObject data = (IDataObject)formatter.Deserialize(ms);
            Clipboard.SetDataObject(data, true); // true = 複本模式,應用退出後仍保留
        }
    }
}

使用示例


// 備份
byte[] clipboardBackup = ClipboardEx.Backup();

// 佔用剪貼板做臨時操作
Clipboard.SetText("Temp");
SendKeys.SendWait("^v");

// 恢復
ClipboardEx.Restore(clipboardBackup);

注意事項

  • BinaryFormatter 已過時/不安全:.NET 5+ 建議改用 System.Text.Json + 自定義序列化,或 protobuf-net。
  • COM 物件無法序列化:某些格式 (如 FileDrop 包含 Shell IDList) 內部持有非托管指針,序列化會失敗。需捕獲異常並降級處理。
  • 大數據量性能:截圖/大文件複製時內存占用大,可考慮異步或分塊。

替代方案:Windows API 級備份

參考最佳回答中的 C++ Builder 代碼,直接操作 OpenClipboard/EnumClipboardFormats/GetClipboardData/GlobalLock 逐格式拷貝內存塊,最完整但需 P/Invoke。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved