Question

Je viens de mettre une solution VS 2008 contenant WinForms, les bibliothèques d'usage général, et une application Web pour VS 2010, mais tous les projets encore .NET 3.5 cibler SP 1. Je utiliser cette technique pour générer XmlSerializers pour mes bibliothèques d'usage général. Les WinForms application bien des pistes. Lorsque mon application Web tente d'exécuter l'utilisation de ces bibliothèques qui font référence à la même XmlSerializers, il jette les éléments suivants:

  

Erreur de serveur dans '/ WebSubscribers'   Application. Impossible de charger le fichier ou   Assemblée   « Ceoimage.Basecamp.XmlSerializers » ou   une de ses dépendances. cet ensemble   est construit par un moteur d'exécution plus récent que le   exécution actuellement chargé et ne peut pas être   chargé. Description: non prise en charge   exception a eu lieu au cours de la   exécution de la demande Web en cours.   S'il vous plaît examiner la trace de la pile pour plus   informations sur l'erreur et   il a pris naissance dans le code.

     

Détails de l'exception: System.BadImageFormatException: Impossible de charger le fichier ou l'assemblage « Ceoimage.Basecamp.XmlSerializers » ou une de ses dépendances. Ceci est l'assemblage construit par un moteur d'exécution plus récent que le moteur d'exécution actuellement chargé et ne peut pas être chargé.

Je l'ai regardé les références du XmlSerializer en utilisant NET Reflector et voir référence à la fois les versions 2.0 et 4.0 de mscorlib ainsi que les versions 3.5 et 4.0 de System.Data.Linq. Étrangement, il utilise uniquement la version 4.0 de System.Xml. C'est probablement mon problème là.

Comment puis-je obtenir l'application Web pour exécuter l'utilisation de ces XmlSerializers? Quand je simplement les supprimer XmlSerializers, l'application Web fonctionne très bien. Ceci est une option, mais comment puis-je forcer MSBUILD à créer serializers pour une version spécifique du CLR?

Voici la tâche MSBuild ajouter des fichiers de projet que les forces de la création des XmlSerializers:

<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>
Était-ce utile?

La solution 3

Je trouve que je peux spécifier explicitement le chemin d'outils de tâche sgen utiliser la version 3.5, comme suit:

<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">

Autres conseils

MSBuild 4 sera (devrait ...) utiliser des outils pour construire 3.5 3.5 projets. Cependant, il semble que cela ne fonctionne pas où les 3.5 outils et utilise les outils 4.0. Le résultat est qu'il est construit correctement votre projet 3.5 (avec des ensembles CLR 2.0.50727), mais l'outil 4.0 sgen.exe génère Ceoimage.Basecamp.XmlSerializers.dll comme un ensemble CLR 4.0.30319.

MSBuild utilise le registre pour obtenir le chemin des outils v3.5. Les tâches MSBuild qui nécessitent des outils SDK v3.5 retomberont sur le chemin de v4.0 si le chemin vers les 3.5 outils ne peuvent pas être identifiés - regard sur la logique utilisée pour définir la propriété TargetFrameworkSDKToolsDirectory dans C: \ Windows \ Microsoft. NET \ Framework \ v4.0.30319 de les Microsoft.NETFramework.props si vous êtes vraiment intéressé.

Vous pouvez diagnostiquer et résoudre les problèmes de registre possibles comme suit:

Installer Process Monitor et mettre en place un filtre pour accès au Registre du moniteur par msbuild (classe de l'événement: Registre, processus Nom: msbuild.exe, tous les types de résultat)

Exécuter votre build

Rechercher Process Monitor pour une mise en correspondance d'accès RegQueryValue "MSBuild \ ToolsVersions \ 4.0 \ SDK35ToolsPath". Notez que cela pourrait être être sous soit "HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft" ou "HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft"

Si vous avez un oeil à cette clé dans le Registre, vous verrez qu'il alias une autre valeur de registre, par exemple "$ (Registre: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SDKs \ Windows \ v7.1 \ winsdk-NetFx35Tools-x86 @ Dossier_installation)" Peu de temps après cela, vous verrez probablement un résultat « NOM INTROUVABLE », comme tente de msbuild pour charger la valeur de la clé spécifiée.

Il doit être clair que les clés que vous devez ajouter / modifier ici.

Il y a quelques raisons possibles pour lesquelles les valeurs de registre sont erronées. Dans mon cas, un problème avec l'installation de Microsoft v7.1 SDK signifie que les clés de registre ont été nommés de manière incorrecte, ce qui a été identifié comme un bug ici:

Êtes-vous dépendant de quoi que ce soit spécifique 4.0?

Si vous invoquez MSBuild 4.0, vous obtiendrez 4.0 outils. Si vous invoquez MSBuild 3.5, vous obtiendrez des outils 3.5 (qui est ce que vous voulez que vous hébergez clairement dans un CLR 2.0).

L'autre option est de mettre le CLR 4.0 sur votre serveur Web. Si ce n'est pas ouvert, vous ne devriez pas avoir une 4.0 substance ciblée dans votre flux.

scroll top