Pergunta

Este código produz um FileNotFoundException, mas em última análise, é executado sem problema:

void ReadXml()
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
    //...
}

Aqui é a exceção:


Uma primeira excepção oportunidade de tipo 'sistema.io.filenotfoundexception' em mscorlib.dll

Informações adicionais: não foi possível carregar arquivo ou assembly 'MyAssembly.XmlSerializers, Version = 1.4.3190.15950, Culture = neutral, PublicKeyToken = null' ou uma de suas dependências. O sistema não pode encontrar o arquivo especificado.


Parece que o quadro gera automaticamente a serialização de montagem, se não for encontrada. I pode gerá-lo manualmente usando sgen.exe, o que alivia a exceção.

Como posso obter o Visual Studio para gerar o XML Serialization montagem automaticamente?


Update: A Gerar assembly de serialização:. Na configuração não parece fazer qualquer coisa

Foi útil?

Solução

Isto é como eu consegui fazê-lo, modificando o script MSBUILD no meu arquivo .csproj:

Primeiro, abra seu arquivo csproj como um arquivo em vez de como um projeto. Vá até o final do arquivo até encontrar este código comentado, pouco antes do fim da tag do projeto:

<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->

Agora só inserir o nosso próprio alvo AfterBuild excluir qualquer existentes XmlSerializer e SGen nossa própria, assim:

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
   <!-- Delete the file because I can't figure out how to force the SGen task. -->
   <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="$(TargetFrameworkSDKToolsDirectory)"
     Platform="$(Platform)">
      <Output
       TaskParameter="SerializationAssembly"
       ItemName="SerializationAssembly" />
   </SGen>
</Target>

que funciona para mim.

Outras dicas

Como Martin explicou em sua resposta , girando sobre geração de serialização de montagem através das propriedades do projeto não é suficiente porque a tarefa SGen está adicionando a opção /proxytypes à linha de comando sgen.exe.

A Microsoft tem um documentado MSBuild propriedade que lhe permite desativar a interruptor /proxytypes e faz com que a Task SGen para gerar as assemblagens de seriação, mesmo que haja nenhum tipo de proxy na assembléia.

SGenUseProxyTypes

Um valor booleano que indica se os tipos de proxy deve ser gerado por Sgen.exe. O alvo SGen usa essa propriedade para definir o sinalizador UseProxyTypes. Esta propriedade padrão é true, e há há UI para mudar isso. Para gerar o conjunto de serialização tipos não-webservice, adicione essa propriedade para o arquivo de projeto e configurá-lo para false antes de importar os Microsoft.Common.Targets ou os C # / VB.targets

Como a documentação sugere que você deve modificar o arquivo de projeto com a mão, mas você pode adicionar a propriedade SGenUseProxyTypes à sua configuração para permitir a geração. Sua configuração de arquivos de projeto iria acabar procurando algo como isto:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <!-- Snip... -->
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <SGenUseProxyTypes>false</SGenUseProxyTypes>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <!-- Snip... -->
    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
    <SGenUseProxyTypes>false</SGenUseProxyTypes>
  </PropertyGroup>

As outras respostas para essa pergunta já mencionamos o Projeto Propriedades-> construção -> Gerar serialização Assembléias definindo mas por padrão isso só vai gerar a montagem se houver " Web XML serviço tipos de proxy " no projeto.

A melhor maneira de entender o comportamento exato do Visual Studio é para examinar o GenerateSerializationAssemblies alvo dentro do C: \ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 ** Microsoft.Common. alvo arquivo **.

Você pode verificar o resultado desta tarefa de compilação do Visual Studio saída janela e selecione build do Mostrar saída de : suspensa caixa. Você deve ver algo ao longo das linhas

C: \ Program Files \ Microsoft Visual Studio 8 \ SDK \ v2.0 \ bin \ sgen.exe /assembly:D:\Temp\LibraryA\obj\Debug\LibraryA.dll / proxytypes / referência: .. / compilador: / delaysign- LibraryA -> D: \ Temp \ LibraryA \ bin \ Debug \ LibraryA.dll

O ponto chave aqui é o proxytypes interruptor /. Você pode ler sobre os vários parâmetros para a XML Serializer Generator Tool ( Sgen.exe)

Se você está familiarizado com MSBuild você pode personalizar as GenerateSerializationAssemblies alvo para essa tarefa SGen tem um atributo de UseProxyTypes = "false" em vez de verdade, mas então você precisa levar em conta toda a responsabilidade associada de personalizar o sistema Visual Studio / MSBuild. Alternativamente, você pode simplesmente estender seu processo de construção para chamar SGen manualmente sem a opção / proxytypes.

Se você ler a documentação para SGen eles são bastante claro que a Microsoft queria limitar o uso desta facilidade. Dada a quantidade de ruído sobre este tema, é bastante claro que a Microsoft não fez um grande trabalho de documentar a experiência Visual Studio. Existe ainda um Ligação item de feedback para esta questão ea resposta não é grande.

criar uma nova definição de tarefa SGen quebra uma mosca na roda. apenas definir as variáveis ??necessárias para fazer o trabalho tarefa como pretendido. De qualquer forma a documentação do Microsoft carece de algumas informações importantes.

etapas de pré-serialização gerar conjuntos

(com peças de http://msdn.microsoft.com/en-us/library/ff798449 aspx )

  1. No Visual Studio 2010, no Solution Explorer, clique com o projeto para o qual você deseja gerar assemblies de serialização, e clique em Descarregar Project.
  2. No Solution Explorer, clique com o projeto para o qual você deseja gerar assemblies de serialização, e clique em Editar .csproj.
  3. No arquivo .csproj, imediatamente após o elemento <TargetFrameworkVersion>v?.?</TargetFrameworkVersion>, adicione os seguintes elementos:

    <SGenUseProxyTypes>false</SGenUseProxyTypes> <SGenPlatformTarget>$(Platform)</SGenPlatformTarget>

  4. No arquivo .csproj, em cada plataforma de configuração

    por exemplo. <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">

    adicione a seguinte linha:

    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>

  5. Salvar e fechar o arquivo .csproj.

  6. No Solution Explorer, clique com o projeto que você acabou de editar e clique em Atualizar Projeto.

Este procedimento gera um conjunto adicional chamado .xmlSerializers.dll em sua pasta de saída. Você precisará implantar essa montagem com a sua solução.


Explicação

SGen por padrão apenas para tipos de proxy gera para “Qualquer CPU”. Isso acontece se você não definir as variáveis ??de acordo no seu arquivo de projeto.

SGenPlatformTarget é necessária para corresponder ao seu PlatformTarget. Eu tendo a pensar que este é um bug no modelo de projeto. Por que a plataforma de destino SGen diferir do seu projecto de? Se isso acontecer você receberá uma exceção de tempo de execução

0x80131040: O localizada montagem é definição manifesto não corresponde à referência do assembly

Você pode localizar a definição da tarefa msbuild através da análise de seu arquivo de projeto:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

onde MSBuildToolsPath depende do seu <TargetFrameworkVersion> http://msdn.microsoft.com/en-us/library /bb397428.aspx

Olhe dentro da definição de tarefa SGen para TargetFrameworkVersion 4,0 a partir de

caminho de instalação Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Microsoft.CSharp.targets

para ver as variáveis ??indocumentados como $ (SGenPlatformTarget) você está livre para colocar em seu arquivo de projeto

<Target
    Name="GenerateSerializationAssemblies"
    Condition="'$(_SGenGenerateSerializationAssembliesConfig)' == 'On' or ('@(WebReferenceUrl)'!='' and '$(_SGenGenerateSerializationAssembliesConfig)' == 'Auto')"
    DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
    Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
    Outputs="$(IntermediateOutputPath)$(_SGenDllName)">

    <SGen
        BuildAssemblyName="$(TargetFileName)"
        BuildAssemblyPath="$(IntermediateOutputPath)"
        References="@(ReferencePath)"
        ShouldGenerateSerializer="$(SGenShouldGenerateSerializer)"
        UseProxyTypes="$(SGenUseProxyTypes)"
        KeyContainer="$(KeyContainerName)"
        KeyFile="$(KeyOriginatorFile)"
        DelaySign="$(DelaySign)"
        ToolPath="$(SGenToolPath)"
        SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
        EnvironmentVariables="$(SGenEnvironment)"
        SerializationAssembly="$(IntermediateOutputPath)$(_SGenDllName)"
        Platform="$(SGenPlatformTarget)"
        Types="$(SGenSerializationTypes)">
            <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/>
    </SGen>
</Target>

Em caso de alguém corre para este problema de repente, depois de tudo estava funcionando bem antes: Para mim, tinha a ver com a opção "Enable Just My Code (só conseguiu)" checkbox ser desmarcada no menu de opções (Opções -> Depuração) (que foi desligado automaticamente depois de instalar o .NET Reflector).

EDIT: O que quer dizer, é claro, que esta excepção estava acontecendo antes, mas quando "permitir apenas o meu código" está desligado, o assistente de depuração (se estiver ativado), irá parar neste ponto, quando acionada.

Estou um pouco atrasado para a festa, mas eu achei a resposta anterior difícil trabalhar com. Especificamente Visual Studio iria falhar sempre que eu tentava visualizar as propriedades do meu projeto. Eu acho que isso foi devido ao fato de que ele não é mais entendida como ler o arquivo csproj. Dito isto ...

Adicione a seguinte a sua linha de comando evento pós-compilação:

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sgen.exe" "$(TargetPath)" /force

Esta alavancagem sgen.exe vontade diretamente para reconstruir o XML serialização de montagem cada vez que você construir seu projeto para Debug ou Release.

Examinar as propriedades na solução. Na guia de construção na parte inferior há um menu suspenso chamado "Gerar serialização de montagem"

A solução ligeiramente diferente do fornecido pelo cérebro de backup poderia ser para especificar diretamente o direito alvo plataforma onde você tem que usar -lo assim:

<!-- Check the platform target value and if present use that for a correct *.XmlSerializer.dll platform setup (default is MSIL)-->
<PropertyGroup Condition=" '$(PlatformTarget)'=='' ">
  <SGenPlatform>$(Platform)</SGenPlatform>
</PropertyGroup>
<PropertyGroup Condition=" '$(PlatformTarget)'!='' ">
  <SGenPlatform>$(PlatformTarget)</SGenPlatform>
</PropertyGroup>

<!-- Delete the file because I can't figure out how to force the SGen task. -->
<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)"
  SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
  EnvironmentVariables="$(SGenEnvironment)"
  Platform="$(SGenPlatform)">
  <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
</SGen>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top