问题
We have an old program version where we put a serializable class into the clipboard. For this example lets say something like this:
namespace ClipboardLibrary
{
[Serializable]
public class ClipboardData
{
public string Content { get; set; }
}
}
Now in the new version to keep it for this example simple the class looks the same except the namespace was changed like so:
namespace ClipboardLibrary.OtherNamespace
{
[Serializable]
public class ClipboardData
{
public string Content { get; set; }
}
}
When I copy now from the old version - where it is done by simply call SetData(someKey, clipboardData)
and try to get the deserialize the data via Clipboard.GetData(someKey)
I get a serialization exception:
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.
...
I am sorry of the German text here. What it says is that the type ClipboardLibrary.ClipboardData
could not be found, which makes obvious sense.
Is there a possibility to retrieve the data anyway somehow?
回答1:
You can reference old assembly in the new one and obtain ClipboardLibrary.ClipboardData
Type
via deserialization without exceptions. And implement in the new assembly convertor from ClipboardLibrary.ClipboardData
to ClipboardLibrary.OtherNamespace.ClipboardData
.
回答2:
I'm not sure how to make it work when interacting with Clipboard
. Because deserialization isn't with our control(AFAIK).
If you're directly dealing with BinaryFormatter
you can create a custom SerializationBinder as below.
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);
}
With that, we're asking the BinaryFormatter
to load ClipboardLibrary.OtherNamespace.ClipboardData
type when it asks for ClipboardLibrary.ClipboardData
. Sort of type redirection.
回答3:
Probably the easiest solution would be to define a class in the old namespace along the one in the new namespace and then after it deserializes successfully map the old one to the new one.
来源:https://stackoverflow.com/questions/29922516/reading-old-clipboard-data-in-new-program-version-in-c-sharp