11

Acabo de actualizar una solución VS 2008 que contiene WinForms, bibliotecas de uso general y una aplicación web para VS 2010, pero todos los proyectos aún se dirigen a .NET 3.5 SP 1. Utilizo this technique para generar XmlSerializers para mis bibliotecas de uso general. La aplicación WinForms funciona bien. Cuando mi aplicación web intenta ejecutar el uso de estas bibliotecas que hacen referencia a los mismos XmlSerializers, que arroja el siguiente:¿Puede VS.NET 2010/MSBUILD producir XmlSerializers para .NET 3.5 SP1?

Error de servidor en la aplicación '/' WebSubscribers. No se pudo cargar el archivo o el ensamblado 'Ceoimage.Basecamp.XmlSerializers' o una de sus dependencias. Este ensamblado está creado por un tiempo de ejecución más reciente que el tiempo de ejecución actualmente cargado y no puede tener cargado. Descripción: Ocurrió una excepción no controlada durante la ejecución de la solicitud web actual . Revise el seguimiento de la pila para obtener más información acerca del error y dónde se originó el código .

Detalles de la excepción: System.BadImageFormatException: No se pudo cargar el archivo o ensamblado 'Ceoimage.Basecamp.XmlSerializers' o una de sus dependencias. Este ensamblado está creado por un tiempo de ejecución más nuevo que el tiempo de ejecución cargado actualmente y no se puede cargar.

He mirado en las referencias de la XmlSerializer usando .NET Reflector y ver que hace referencia tanto a las versiones 2.0 y 4.0 de mscorlib así como las 3.5 y 4.0 versiones de System.Data.Linq. Extrañamente, solo usa la versión 4.0 de System.Xml. Ese es probablemente mi problema allí mismo.

¿Cómo puedo hacer que la aplicación web se ejecute utilizando estos XmlSerializers? Cuando simplemente elimino esos XmlSerializers, la aplicación web funciona bien. Esta es una opción, pero ¿cómo puedo forzar a MSBUILD a crear serializadores para una versión específica del CLR?

Aquí es la tarea de MSBuild agrego a los archivos que obliga a la creación de los XmlSerializers proyectar: ​​

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)"> 
<Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" /> 
<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)"> 
    <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" /> 
</SGen> 
</Target> 
+1

se debe añadir esa edición como una respuesta así que puede votarlo, parece ser la mejor solución :) – Lucas

Respuesta

2

He encontrado que puedo especificar explícitamente ruta de herramientas de la tarea SGEN utilizar la versión 3.5, así:

<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin"> 
+0

¿Estás cambiando el archivo de objetivos o estás modificando los archivos de tus proyectos de alguna forma? No sé cómo aplicar esto a mi entorno ... –

+0

Esto fue hace mucho tiempo, pero estoy bastante seguro de que edité el archivo CSPROJ directamente. – flipdoubt

2

¿Eres dependiente de algo específico 4.0?

Si invoca MSBuild 4.0, obtendrá 4.0 herramientas. Si invoca MSBuild 3.5, obtendrá 3.5 herramientas (que es lo que desea, ya que está alojando claramente en un 2.0 CLR).

La otra opción es poner 4.0 CLR en su servidor web. Si eso no está abierto, no deberías tener 4.0 cosas objetivo en tu transmisión.

+0

Acabo de comprobar uno de mis proyectos y encontré que solo hace referencia a los ensamblados de framework 2.0 y 3.5. Una cosa que noto, sin embargo, es que la propiedad 'Specific Version' de cada framework hace referencia a' false'. Cuando descargo un proyecto y eche un vistazo al archivo .CSPROJ, la etiqueta de propiedad menciona las herramientas 4.0 como lo siguiente: '' Cuando cambio 'ToolsVersion' a' 3.5', VS 2010 convierte el proyecto y devuelve el valor a '4.0'. – flipdoubt

+0

@flipdoubt: VS2010 forcing 4.0 toolsversion es un problema conocido (tiene una búsqueda). el problema aquí es que la tarea de SGen que se está importando es la tarea 4.0 sgen, que por defecto será 4.0 SGen.exe. Tal vez, al reemplazar ToolPath en el trabajo de 3.5 SGen mioght. –

+0

Y luego miré tu edición. Creo que es la mejor solución, dado que ejecutar tus proyectos de ToolsVersion 4.0 a través de MSBuild 3.5 no va a ser una solución a largo plazo –

8

MSBuild 4 se (debe ...) utilizar herramientas para construir 3,5 3,5 proyectos. Sin embargo, parece que no se puede determinar dónde están las herramientas 3.5 y está utilizando las herramientas 4.0. El resultado es que está construyendo correctamente su proyecto 3.5 (con ensamblados CLR 2.0.50727), pero la herramienta 4.0 sgen.exe está generando Ceoimage.Basecamp.XmlSerializers.dll como un ensamblado CLR 4.0.30319.

MSBuild utiliza el registro para obtener la ruta a las herramientas v3.5. Las tareas de MSBuild que requieren las herramientas v3.5 SDK volverán a la ruta v4.0 si la ruta al 3.No se pueden identificar 5 herramientas: observe la lógica utilizada para establecer la propiedad TargetFrameworkSDKToolsDirectory en C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Microsoft.NETFramework.props si realmente está interesado.

Puede diagnosticar y solucionar posibles problemas de registro de la siguiente manera:

Instalar el monitor de procesos y configurar un filtro para controlar el acceso al registro por msbuild (clase de eventos: Registro, Nombre del proceso: msbuild.exe, todos los tipos de resultado)

ejecutar su construcción

Buscar monitor de procesos para una coincidencia de acceso RegQueryValue "MSBuild \ ToolsVersions \ 4.0 \ SDK35ToolsPath". Tenga en cuenta que esto podría estar bajo "HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft" o "HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft"

Si mira esta clave en el registro, verá que alias otro registro valor, por ejemplo "$ (Registro: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SDKs \ Windows \ v7.1 \ WinSDK-NetFx35Tools-x86 @ InstallationFolder)" Poco después de esto, probablemente verá un resultado "NAME NOT FOUND" cuando msbuild intenta cargar el valor de la clave especificada.

Debe estar claro qué teclas necesita agregar/modificar desde aquí.

Existen varios motivos posibles por los que los valores de registro son incorrectos. En mi caso, un problema con la instalación v7.1 SDK de Microsoft significaba que las claves de registro fueron nombrados de forma incorrecta, que ha sido identificado como un error aquí:

http://connect.microsoft.com/VisualStudio/feedback/details/594338/tfs-2010-build-agent-and-windows-7-1-sdk-targeting-net-3-5-generates-wrong-embedded-resources

+0

+1 para la explicación –

+0

Gracias por esta respuesta. Estoy combinando esto con http://stackoverflow.com/a/2739132/281084 para resolver mi problema –

Cuestiones relacionadas