C# 用C语言读取新程序版本中的旧剪贴板数据#

C# 用C语言读取新程序版本中的旧剪贴板数据#,c#,serialization,clipboard,C#,Serialization,Clipboard,我们有一个旧的程序版本,其中我们将一个可序列化的类放入剪贴板。对于本例,我们可以这样说: namespace ClipboardLibrary { [Serializable] public class ClipboardData { public string Content { get; set; } } } 现在,在新版本中,为了保持此示例的简单性,该类看起来相同,只是名称空间更改如下: namespace ClipboardLibrary

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

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
,这显然是有道理的


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

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

我不确定在与
剪贴板
交互时如何使其工作。因为反序列化与我们的控件(AFAIK)无关

如果您直接处理的是
BinaryFormatter
,您可以创建一个如下的自定义设置

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);
}

这样,我们要求
BinaryFormatter
在请求
ClipboardLibrary.OtherNamespace.ClipboardData
时加载
ClipboardLibrary.ClipboardData
。类型重定向排序。

您可以在新程序集中引用旧程序集,并通过反序列化获得
剪贴板库。剪贴板数据
类型
,无异常。并在新的程序集转换器中实现从
ClipboardLibrary.ClipboardData
ClipboardLibrary.OtherNamespace.ClipboardData

您可以在尝试反序列化对象的位置共享代码吗?请参见上面的异常。我只需要调用剪贴板。GetData(someKey)查看一下custom,还有一个潜在的问题是,客户已经有了产品,无法对旧版本进行更改。其他程序如何将数据设置到剪贴板?这不会有什么帮助。我将尝试并报告。您可以从另一个类继承一个(新的?)类,以避免重复的代码,假设它们没有更改,我们只是修复了类的名称空间。在这种情况下,我将不得不随身携带旧版本中的垃圾。@adricadar哦,如果我们现在没有该类型,你会怎么做?你的代码很棒,解决了这个问题,你可以在构造函数或其他地方传递名称空间,这种方式将更通用。这是如何解决问题的?我如何使用剪贴板的这个?@Yggdrasil你能发布异常的堆栈跟踪吗。让我看看是否可以从中获得更多信息。如果剪贴簿数据之外有其他类型的名称空间未移动,因此仍在同一名称空间中,是否会导致冲突?因为您已将类
ClipboardData
从旧NS移动到新NS,您需要将当前的
ClipboardData
类与
OtherNamespace.ClipboardData
一起使用,而不仅仅是
ClipboardData
,直到您的应用程序的所有旧版本停止生产,并且您可以删除旧定义