Recientemente actualizamos un proyecto muy grande de .NET framework 3.5 a 4, e inicialmente todo parecía funcionar de la misma manera. Pero ahora los errores han comenzado a aparecer en las operaciones de copiar y pegar. He logrado hacer una pequeña aplicación reproducible, que muestra el comportamiento diferente en .NET 3.5 y 4. También encontré una solución alternativa (serializar manualmente los datos en el portapapeles), pero me queda una necesidad de saber "por qué" hay una diferencia en el comportamiento.El portapapeles se comporta de manera diferente en .NET 3.5 y 4, pero ¿por qué?
Ésta es la aplicación de prueba pequeña que hice:
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
namespace ClipboardTest
{
public class Program
{
[Serializable]
public class Element
{
public Element(string name)
{
this.name = name;
}
public string name;
}
public static List<Element> TestSerializer(List<Element> obj)
{
var memoryStream = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, obj);
return (List<Element>)formatter.Deserialize(new MemoryStream(memoryStream.GetBuffer()));
}
public static List<Element> TestClipboard(List<Element> obj)
{
Clipboard.SetDataObject(obj);
return (List<Element>)Clipboard.GetDataObject().GetData(typeof(List<Element>));
}
public static void DumpObject(string testName, List<Element> obj)
{
if (obj == null)
{
Console.WriteLine("{0} : List is null", testName);
return;
}
foreach (var prop in obj)
{
Console.WriteLine("{0} : {1}", testName, prop.name);
}
}
[STAThread]
static void Main()
{
var copyData = new List<Element> { new Element("all good") };
DumpObject("Serializer", TestSerializer(copyData));
DumpObject("Clipboard", TestClipboard(copyData));
}
}
}
.NET 3.5 de salida:
Serializador: todo bien
portapapeles: todo bien
.NET 4 de salida:
Serializador : todo bien
Portapapeles: La lista es nula
He consultado la fuente de .NET para la clase DataObject Clipboard &, pero no pude ver qué serializador se utilizó. La documentación de MSDN dice que el tipo debe ser serializable, que en este caso son las clases List <> y Element. Copiar un objeto Element funciona bien, pero tan pronto como copie una lista de elementos, se rompe.
Para probar, he creado 2 proyectos C# "Aplicación de consola" en Visual Studio 2010 SP1. El primer proyecto que me queda con la configuración predeterminada "Marco de destino" de ".NET Framework 4 Client Profile". El segundo proyecto que modifiqué para usar ".NET Framework 3.5 Client Profile".
información adicional sobre las Formas mi versión de DLL:
Nombre original del archivo: System.Windows.Forms.dll
versión Archivo/versión prouct: 4.0.30319.235
Idioma: Inglés (Estados Unidos)
Fecha de modificación: 16 -02-2012 22:50
Para mí funciona bien con .NET 4 ... imprime "todo bien" para ambos casos –
Hm, en mi máquina, funciona bien con 3.5 y falla en 4.0 como marco de destino, al igual que el OP estados (arroja una excepción COM "Estructura de FORMATETC inválida" en Clipboard.GetDataObject(). GetData()). Además, encontré un problema similar aquí: https://connect.microsoft.com/VisualStudio/feedback/details/488627/comexception-invalid-formatetc-structure-while-pasting-marshalbyref-data-from-datagridview – Alan
(utilizando VS2010 SP1 en XP SP3) – Alan