在C#中使用新程序版本读取旧剪贴板数据

时间:2015-04-28 14:40:29

标签: c# serialization clipboard

我们有一个旧的程序版本,我们将可序列化的类放入剪贴板。对于这个例子,我们可以这样说:

namespace ClipboardLibrary
{
    [Serializable]
    public class ClipboardData
    {
        public string Content { get; set; }
    }
}

现在在新版本中,为了保持这个例子的简单,这个类看起来是一样的,除了命名空间是这样的:

namespace ClipboardLibrary.OtherNamespace
{
    [Serializable]
    public class ClipboardData
    {
        public string Content { get; set; }
    }
}

当我现在从旧版本复制时 - 只需调用SetData(someKey, clipboardData)并尝试通过Clipboard.GetData(someKey)对数据进行反序列化,我得到序列化异常:

System.Runtime.Serialization.SerializationException was unhandled
  HResult=-2146233076
  Message=Der für die Deserialisierung benötigte Typ "ClipboardLibrary.ClipboardData" kann nicht geladen werden.
  Source=mscorlib
  StackTrace:
      bei System.Runtime.Serialization.ObjectManager.DoFixups()
      bei System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
      bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
      bei System.Windows.DataObject.OleConverter.ReadObjectFromHandle(IntPtr handle)
      bei System.Windows.DataObject.OleConverter.GetDataFromHGLOBAL(String format, IntPtr hglobal)
      bei System.Windows.DataObject.OleConverter.GetDataFromOleHGLOBAL(String format, DVASPECT aspect, Int32 index)
      bei System.Windows.DataObject.OleConverter.GetDataFromBoundOleDataObject(String format, DVASPECT aspect, Int32 index)
      bei System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert, DVASPECT aspect, Int32 index)
      bei System.Windows.DataObject.OleConverter.GetData(String format, Boolean autoConvert)
      bei System.Windows.DataObject.GetData(String format, Boolean autoConvert)
      bei System.Windows.Clipboard.GetDataInternal(String format)
      bei System.Windows.Clipboard.GetData(String format)
      bei CopyPaste.MainWindow.Button_Click_1(Object sender, RoutedEventArgs e) in c:\Users\twilker\Documents\Visual Studio 2013\Projects\CopyPaste\CopyPaste\MainWindow.xaml.cs:Zeile 42.
      ...

我对这里的德语文本感到抱歉。它所说的是ClipboardLibrary.ClipboardData类型无法找到,这显然是有意义的。

是否有可能以某种方式检索数据?

3 个答案:

答案 0 :(得分:3)

您可以在新的程序集中引用旧程序集,并通过反序列化获得ClipboardLibrary.ClipboardData Type,无例外。并在ClipboardLibrary.ClipboardDataClipboardLibrary.OtherNamespace.ClipboardData的新程序集转换器中实现。

答案 1 :(得分:2)

我不确定在与Clipboard互动时如何使其发挥作用。因为反序列化不在我们的控制之下(AFAIK)。

如果您直接与BinaryFormatter打交道,可以创建自定义SerializationBinder,如下所示。

public class CustomSerializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        if (typeName == "ClipboardLibrary.ClipboardData")
        {
            return typeof(ClipboardLibrary.OtherNamespace.ClipboardData);
        }
        return Type.GetType(String.Format("{0}, {1}",
                typeName, assemblyName));
    }
}

private ClipboardLibrary.OtherNamespace.ClipboardData DeSerialize(Stream stream)
{
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Binder = new CustomSerializationBinder();
    return (ClipboardLibrary.OtherNamespace.ClipboardData)formatter.Deserialize(stream);
}

有了这个,我们要求BinaryFormatterClipboardLibrary.OtherNamespace.ClipboardData要求时加载ClipboardLibrary.ClipboardData类型。类型重定向排序。

答案 2 :(得分:0)

最简单的解决方案可能是在旧命名空间中沿着新命名空间中的一个类定义一个类,然后在反序列化之后成功地将旧映射映射到新命名空间。