Clipboard.GetText() 等僅支援標準格式,無法處理用戶自定義格式 (如 Excel 範圍、VS 代碼片段、專有業務對象)。逐項枚舉 GetDataPresent 仍會遺漏未知格式。
利用 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);
System.Text.Json + 自定義序列化,或 protobuf-net。FileDrop 包含 Shell IDList) 內部持有非托管指針,序列化會失敗。需捕獲異常並降級處理。參考最佳回答中的 C++ Builder 代碼,直接操作 OpenClipboard/EnumClipboardFormats/GetClipboardData/GlobalLock 逐格式拷貝內存塊,最完整但需 P/Invoke。