none
Mimic / Configure Copy Local (Private) mechanism? RRS feed

  • Question

  • Hello,

    I have a question regarding the implementation of "Copy Local" / Private for References and Project References. I tried to debug into the corresponding MSBuild targets, already searched a while for documentation, but I don't get it yet...

    In a nutshell: can I configure the default behavior of Copy local? Where could I find more information to that? And as an alternative, could I reimplement a similar (but simpler) algorithm for References and Project References? I think I understand how to mimic copying References on my own, but how can I copy the output of project references?

    I want to disable Copy Local's ability to copy implicitly dependent assemblies. I want to enforce, that only the references (and project references) of a test project are copied to the output folder, but nothing else.

    We have a big product here. Many assemblies, a lot of vendors, and a lot of test projects. We already enforce copy local = false for our products and add runtime assemblies via additional MSBuild targets. Our unit tests are run in isolation, i.e. we want full control over what kind of assemblies are loaded during runtime, therefore our build process generates each unit test project into its own folder. However, creating runtime deployment scripts for every single test project seemed very cumbersome, so we tried to rely on Copy Local = true to copy every runtime assembly we need.

    This seems to have strange side effects. Apparently, when referencing 3rd party assemblies, Copy Local analyzes which assemblies may also be needed, and copies them as well from the same hint path. We have a gated check-in with incremental builds here, and sometimes we see that assemblies are present in the test output folders that were never directly referenced. Sometimes however, they are not copied anymore, but the tests still succeed because the output path still contains them after an incremental build. After I clean the output, the tests start failing. This leads to a lot of confusion, because check-ins are accepted through the gated check-in that probably shouldn't, and check-ins fail after cleaning the output directory that should succeed.

    I don't expect a full solution, but can someone hint me into the right direction? I'd really appreciate the help.


    Regards


    • Edited by goppeltm Friday, April 29, 2016 9:01 AM Formatting for easier read
    Friday, April 29, 2016 9:00 AM

Answers

  • When using the version of MSBuild that comes with .NET Framework 4.5.2, the /property:_FindDependencies=false option appears to do the job. In Microsoft.Common.targets, the ResolveAssemblyReferences target passes FindDependencies="$(_FindDependencies)" to the ResolveAssemblyReference task. That then affects the CopyLocalFiles output parameter, the ReferenceCopyLocalPaths item type, and the _CopyFilesMarkedCopyLocal target.

    However, because the name of the property begins with an underscore, I'm not sure it will work the same way in *.targets files that come with later versions of MSBuild.

    Also, if you build a web application project in Visual Studio, it can copy additional files to the output directory without using the Copy task of MSBuild. This does not happen when you run MSBuild.exe yourself.

    Friday, April 29, 2016 7:23 PM

All replies

  • When using the version of MSBuild that comes with .NET Framework 4.5.2, the /property:_FindDependencies=false option appears to do the job. In Microsoft.Common.targets, the ResolveAssemblyReferences target passes FindDependencies="$(_FindDependencies)" to the ResolveAssemblyReference task. That then affects the CopyLocalFiles output parameter, the ReferenceCopyLocalPaths item type, and the _CopyFilesMarkedCopyLocal target.

    However, because the name of the property begins with an underscore, I'm not sure it will work the same way in *.targets files that come with later versions of MSBuild.

    Also, if you build a web application project in Visual Studio, it can copy additional files to the output directory without using the Copy task of MSBuild. This does not happen when you run MSBuild.exe yourself.

    Friday, April 29, 2016 7:23 PM
  • Hello Ranta,

    sorry for the late answer. I would have marked this as answer, too. I tried it, and it does exactly what I need. However, since this seems to be undocumented behavior, I consider this as hack. Would be nice to understand what really happens under the hood.

    Anyway, thx.

    Monday, May 9, 2016 6:10 AM
  • Perhaps you could instead override the ResolveAssemblyReferences target in your project file so that the one defined in Microsoft.Common.targets is not used. That way, you would directly control the FindReferences parameter of the ResolveAssemblyReference task. Microsoft has documented that Visual Studio uses the ResolveAssemblyReferences target when it loads the project, although I suppose the documentation doesn't outright state that the same target is also used when building.

    Tuesday, May 17, 2016 3:07 PM