Pergunta

Eu estou escrevendo um IDE de desenvolvimento do jogo que cria e compila .NET projectos (que eu tenho vindo a trabalhar nos últimos anos) e estou no processo de atualizá-lo para gerar a saída não só para Windows / Visual Studio , mas também para Linux / MonoDevelop (um processo thrillingly simples para .NET, mas ainda requer alguns ajustes).

Como parte deste, eu descobri que é necessário para começar a gerar um arquivo app.config como parte deste para mapear nomes DLL dependentes para nomes de dependência Linux com elementos. Estou confuso sobre quem é responsável por copiar o arquivo app.config para o nome de saída app.exe.config. Em um projeto Visual Studio, o Build Action para app.config parece ser normalmente definido como "Nenhum" e suas configurações indicam que ele não será copiado em qualquer lugar, mas quando Visual Studio compila o projeto gera app.exe.config ( embora eu tenha encontrado às vezes isso seja pouco confiável). Quando eu usar MSBuild para construir um arquivo de solução gerada pelo IDE (para fins de depuração), MSBuild cópias app.config para app.exe.config. Mas quando eu compilar o projeto com CSharpCodeProvider.CompileAssemblyFromFile-lo (naturalmente) não gosta do arquivo de configuração a ser incluído como código-fonte ( "app.config (1,1): Erro CS0116: Um espaço de nomes não contém diretamente membros como campos ou métodos "), e é claro que não copiá-lo para a saída quando eu não incluí-lo como uma entrada. não é minha responsabilidade para simplesmente copiar app.config para app.exe.config de forma independente, ou é uma forma mais padrão de fazer isso?

É programado para tomar o primeiro arquivo.config *? Na minha IDE é concebível que o arquivo app.config seria renomeado ou outro agregado (assim como no Visual Studio). Parece estranho para mim que o IDE tem esta ação secreta para arquivos de configuração (acho MonoDevelop comporta de forma semelhante a este respeito, porque eu não poderia encontrar uma ação especial para arquivos de configuração não quer). Eu não sei como ele mesmo escolhe para quais arquivos esta ação secreta aplica.

Foi útil?

Solução

O compilador C # não se preocupa com o arquivo de configuração em tudo. ambientes de construção (MSBuild e VS) vai cuidar de copiar esse arquivo se.

Outras dicas

Ordem:

  1. primeiro arquivo app.config com ação Nenhum construção, no diretório do projeto
  2. primeiro arquivo app.config com ação de compilação de conteúdo, no diretório do projeto
  3. primeiro arquivo app.config com ação Nenhum construção, em um subdiretório
  4. primeiro arquivo app.config com ação de compilação de conteúdo, em um subdiretório

msbuild / xbuild também permitem que você substituir esse, definindo a propriedade $ (AppConfig).

Eu acho que MSBuild é responsável por copiar. Se você cavar calha arquivos estoque .TARGET, então você provavelmente encontrar directivas correspondente. O VS por si só não copiar.

Note-se também que o Visual Studio faz validar o arquivo de configuração.

Uma resposta um pouco mais técnico - suas referências do projeto Microsoft.CSharp.targets através desta chave no arquivo csproj:

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

Este arquivo iria resolver para algo como c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets, dependendo da sua versão do framework.

Dentro do que você tem esta secção que faz o trabalho:

  <!--
    ============================================================
                                        _CopyAppConfigFile

    Copy the application config file.
    ============================================================
    -->
  <Target
      Name="_CopyAppConfigFile"
      Condition=" '@(AppConfigWithTargetPath)' != '' "
      Inputs="@(AppConfigWithTargetPath)"
      Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">

    <!--
        Copy the application's .config file, if any.
        Not using SkipUnchangedFiles="true" because the application may want to change
        the app.config and not have an incremental build replace it.
        -->
    <Copy
        SourceFiles="@(AppConfigWithTargetPath)"
        DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')"
        OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
        Retries="$(CopyRetryCount)"
        RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
        UseHardlinksIfPossible="$(CreateHardLinksForAdditionalFilesIfPossible)"
            >

      <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>

    </Copy>

  </Target>

O arquivo App.Config parece ser passado como uma variável de ambiente (espera-se a estar presente, mas que define isso, eu não sei):

<ItemGroup>
  <AppConfigWithTargetPath Include="$(AppConfig)" Condition="'$(AppConfig)'!=''">
    <TargetPath>$(TargetFileName).config</TargetPath>
  </AppConfigWithTargetPath>
</ItemGroup>

Editar: Por quanto app.config seleccionada, consulte esta resposta - https: // stackoverflow. com / a / 40293508/492336 .

A manipulação do app.config é especial, ele é tratado pelo nome, o processo de construção irá selecionar o arquivo app.config seguindo esta ordem:

  • Escolha o conjunto valor R $ (AppConfig) no projeto principal.
  • Escolha @ (Nenhum) App.Config na mesma pasta do projeto.
  • Escolha @ (Conteúdo) App.Config na mesma pasta do projeto.
  • Escolha @ (Nenhum) App.Config em qualquer subpasta no projeto.
  • Escolha @ (Conteúdo) App.Config em qualquer subpasta no projeto.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top