O que a configuração privada faz em um ProjectReference em um arquivo de projeto MSBuild?

120

Eu vi isso em um arquivo de projeto outro dia:

<ProjectReference Include="Foo\Bar\Baz.csproj">
    <Project>{A GUID HERE}</Project>
    <Name>Baz</Name>
    <Private>False</Private> <!-- ??? -->
    <ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>

Cada nó em um ProjectReferenceparece ser autoexplicativo (o arquivo de projeto referenciado, GUID, nome a ser mostrado no gerenciador de soluções e se o projeto atual deve ser vinculado ou não ao projeto referenciado) Private, exceto , e a página Itens do projeto MSBuild comuns não t documente esse valor. (Há um Privatecenário documentado para Reference, em vez de ProjectReference- mas tem Never, Always, e PreserveNewestconfigurações, não verdadeiros e falsos)

O que essa configuração faz?

Billy ONeal
fonte
2
No que diz respeito ao MSBuild, ProjectReference é um grupo de itens (ou seja, lista) e Private são os metadados do item para o item incluído. A resposta à sua pergunta está no que qualquer um inclui fazer com ele. Em termos mais gerais, que tipo específico de projeto é? Talvez marque sua pergunta com csharp.
Tom Blodget,
Eu quis dizer "Importações" e não "Inclui".
Tom Blodget,
@malexander: Acho que sua resposta seria boa se você desfizesse a exclusão ...
Billy ONeal
2
@Tom: Claro, estritamente falando isso é verdade. Por outro lado, o ProjectReferenceitem é reconhecido (pelo menos) pela infraestrutura de suporte C # e C ++ MSBuild; parece que ele é tratado principalmente no Microsoft.Common.CurrentVersion.targetsarquivo.
Billy ONeal

Respostas:

126

A Privatemarca mantém a substituição do usuário na caixa de seleção "Copiar local" na pasta Referências do Visual Studio. Isso controla se a referência é usada do GAC ou se ele irá copiar o assembly referenciado para o diretório de compilação.

Embora eu não consiga encontrar nenhuma documentação do MSDN para esse efeito (quelle surpresa), é evidente pelo comportamento e pelo comentário emMicrosoft.Common.CurrentVersion.targets:1742 que é aplicado:

Isso está documentado em MSDN> Itens de projeto comuns do MSBuild e é evidente a partir do comportamento e do comentário emMicrosoft.Common.CurrentVersion.targets:1742 que é aplicado:

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

                                        ResolveAssemblyReferences

    Given the list of assemblies, find the closure of all assemblies that they depend on. These are
    what we need to copy to the output directory.

        [IN]
        @(Reference) - List of assembly references as fusion names.
        @(_ResolvedProjectReferencePaths) - List of project references produced by projects that this project depends on.

            The 'Private' attribute on the reference corresponds to the Copy Local flag in IDE.
            The 'Private' flag can have three possible values:
                - 'True' means the reference should be Copied Local
                - 'False' means the reference should not be Copied Local
                - [Missing] means this task will decide whether to treat this reference as CopyLocal or not.

        [OUT]
        @(ReferencePath) - Paths to resolved primary files.
        @(ReferenceDependencyPaths) - Paths to resolved dependency files.
        @(_ReferenceRelatedPaths) - Paths to .xmls and .pdbs.
        @(ReferenceSatellitePaths) - Paths to satellites.
        @(_ReferenceSerializationAssemblyPaths) - Paths to XML serialization assemblies created by sgen.
        @(_ReferenceScatterPaths) - Paths to scatter files.
        @(ReferenceCopyLocalPaths) - Paths to files that should be copied to the local directory.
    ============================================================
    -->
Mitch
fonte
7
Como Mitch disse, ele controla a configuração Copiar local nas propriedades para uma referência. Além disso, ele pode conter apenas os valores True e False. Se estiver ausente, o valor padrão True será assumido
GPR
4
Se <Private>estiver faltando, não é equivalente a True. Procure por "Bug do MSBuild CopyLocal". Por exemplo, consulte stackoverflow.com/questions/1132243
xmedeko
7
@xmedeko, Correto. Não tenho certeza de onde @GPR obteve "Se estiver ausente, então o valor padrão de True é assumido", pois a resposta diz explicitamente "[Missing] significa que esta tarefa decidirá se deve tratar esta referência como CopyLocal ou não". A maior parte da lógica está emmsbuild\Reference.cs:949
Mitch
É possível que, mesmo se <Private>estiver definido como True, o MSBuild ainda não inclua a referência na saída se não for usado pelo aplicativo? Este é o comportamento atual que estou obtendo localmente ...
Ninja
@Ninja, isso acontece com mais frequência se o MSBuild não puder localizar o assembly referenciado. Se não for usado diretamente pelo código, ele ainda pode ser compilado com êxito. Você pode solucionar problemas com o registro detalhado do procmon ou MSBuild
Mitch
0

Eu quero apenas afirmar, que <Private>false</Private>(que você pode aplicar a ProjectReferences) pode não funcionar ao usar <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Publish" Properties="$(_MSBuildProperties)" />e o projeto $(MSBuildProjectFullPath)tem ProjectReferences que têm <None><CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory></None> . Eu li o código-fonte em https://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets e encontrei a solução. Você precisa definir _GetChildProjectCopyToPublishDirectoryItems=falsepara que um exemplo seja:<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Publish" Properties="TargetFramework=$(TargetFramework);_GetChildProjectCopyToPublishDirectoryItems=false" />

Teroneko
fonte