Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support setting CopyLocal to false on references added by NuGet #329

Closed
eerhardt opened this issue Apr 1, 2015 · 17 comments
Closed

Support setting CopyLocal to false on references added by NuGet #329

eerhardt opened this issue Apr 1, 2015 · 17 comments
Milestone

Comments

@eerhardt
Copy link

eerhardt commented Apr 1, 2015

There are plenty of scenarios where NuGet package authors want CopyLocal set to 'false' on a reference by default after installing their package. One such example is when using the VSIX packaging to create Visual Studio extensions. When CopyLocal is true, the referenced assembly will automatically be packaged into the output VSIX.
Currently, the only way to set CopyLocal to false is to use a powershell script:
http://stackoverflow.com/questions/11105286/create-nuget-package-which-installs-references-with-copy-local-set-to-false
http://nuget.codeplex.com/workitem/1340
http://geekswithblogs.net/JoshReuben/archive/2012/09/23/real-world-nuget.aspx (See section “Forcing ‘copy local=false’)

However, guidance from Yishai Galatzer has been to not use powershell because "they only work from within VS, and they tend to be fragile long term."

NuGet should officially support CopyLocal=false references.

@yishaigalatzer yishaigalatzer added Type:DCR Design Change Request Type:Feature and removed Type:DCR Design Change Request labels Apr 14, 2015
@yishaigalatzer yishaigalatzer added this to the 3.1.0-Beta milestone Apr 14, 2015
@yishaigalatzer
Copy link

@eerhardt have been trying to understand the core reason to prevent copy local to false (at the package level), and I don't see a really good one.

Can you share your scenario, so we can look again at prioritizing this item.

CC @davidfowl

@eerhardt
Copy link
Author

At the time, I was building a VS extension point. In order for VS extensions to consume our APIs, we need to ship them a “Contracts” assembly that they will reference. We will ship this Contracts assembly as a NuGet package. Using the VSIX packaging technology, whenever you have a CopyLocal=true reference, that reference will automatically be included in the output VSIX.

Since our Contracts assembly ships as part of VS, there is no need for a bunch of different VS extensions to package and install multiple copies of this Contracts assembly in each of their VSIXs. The Contracts assembly will already be installed and loaded in VS. Thus, by default we want CopyLocal to be set to ‘false’, so that this Contracts assembly isn’t included in all these extensions’ VSIXs.

Since VS is starting to ship all of its Contracts assemblies as NuGet packages: https://www.nuget.org/profiles/VisualStudioExtensibility, this same scenario can be applied to any VS extension. There is no need for every VS extension to package all of the VS Contracts assemblies in their VSIXs, since VS already has them installed and loaded.

@yishaigalatzer yishaigalatzer modified the milestones: 3.5 Beta, 3.3.0 Mar 10, 2016
@yishaigalatzer
Copy link

The guidance from andrew arnott was not to go this way. #452

@Andrey-Bushman
Copy link

It is very strange that @yishaigalatzer don't understand when it is necessary and marked it as WontFix... Set CopyLocal to false is often required for plugins developing. For example it is required for AutoCAD plugins developing. Of course it is true for plugins developing for other applications also. Reopen this issue, please.

@yishaigalatzer
Copy link

Andrey, please spell out the exact reason. The scenario Eric brought up was not a valid one and the visual studio team recommended not to go there.

@Andrey-Bushman
Copy link

Andrey-Bushman commented Jul 20, 2016

Autodesk company provides AutoCAD .NET API for developers. This API is part of ObjectARX SDK. It requires set CopyLocal to false for its managed DLL files. Look here the position number 3, please:

Browse to the install directory for AutoCAD Civil 3D, and select the base libraries acdbmgd.dll, acmgd.dll, accoremgd.dll, AecBaseMgd.dll, and AeccDbMgd.dll.
Note:

These are the base AutoCAD and AutoCAD Civil 3D managed libraries. Your .NET assembly can use classes defined in additional libraries.

To allow debugging and reduce the disk space requirements for your projects, select these libraries in the Visual Studio Solution Explorer, and set the Copy Local property to False.

So, it is necessary for each developer which writes the extensions for AutoCAD or its vertical products. Without changing of this property the debugging of AutoCAD extensions will not be possible.

@yishaigalatzer
Copy link

I see, this is a similar scenario to the visual studio extensibility. I would assume that a developer should not reship these libraries and they should go through a common package that Autodesk ships (and revs us necessary), I would advise contacting them for that rather than reshipping and bundling your own.

Now back to your question: are you shipping these internally or do you plan to ship on nuget.org?

I believe you can achieve the guidance for either packages.config scenarios OR project.json scenarios OR both, each has a slightly different solution. As we are trying to slowly move everyone to the project.json model, I would suggest starting with that:

Just add the dlls to a ref folder (requires vs 2015)

If you want it for packages.config as far as I know most people use an install.ps1 script to change the flag.

Last method that will work everywhere is to create an msbuild target and include the references any way you choose to while disabling copy to output.

@BenKmann
Copy link

BenKmann commented Nov 8, 2016

In the current Release Notes ( https://docs.nuget.org/ndocs/release-notes/nuget-3.5-RTM ) you mark this Ticket as a new Feature.
But it seems to be, that this isn't the case.

I really would like this as a Feature. It is a useful Feature for every AddIn Developer, who wants to use (Internal) Nuget-Packages which are not allowed to be copied to the output Folder, because Frameworks like Microsoft MEF don't like it, when you double the Assemblies in your AddIn Folder that the Executable already has loaded.

The Problem with the Alternatives, like the install.ps1 skript from Stackoverflow is, that it produces duplicate/new CopyLocal Entries in the csproj-File and makes the csproj buggy (as the user here http://stackoverflow.com/questions/11105286/create-nuget-package-which-installs-references-with-copy-local-set-to-false#comment64690207_11106429 also describes).

@borland
Copy link

borland commented Jul 31, 2017

We have this scenario as well, I'll explain ours:

We have a base application, which includes references to various Nuget packages.

Our application supports plugins - we have a "Plugins" folder where we drop dll's in, and they're all loaded using the Managed Extensibility Framework (MEF).

When creating a plugin dll, those plugins neccessarily need to add references to components from the base application (interfaces, utility libraries, contracts and such). Some of those in turn take a dependency on third party things like Newtonsoft.Json, Microsoft.WebApi.Core and so forth.

We used to largely ignore Nuget and just have all our DLL's stored locally in TFS, and as such we'd add references manually to dll's and set copy local: false on them, which was fine.
If someone forgot to set copy local: false, then there'd end up being a copy of Newtonsoft.Json, WebApi.Core and whatever else in both the base application directory AND the plugins sub directory. This would cause two copies of things to get loaded and screw things up, usually causing our application to fail to start.

We've now switched various things over to Nuget and the new CSProj format using and the inability to set copy local: false on these things results in the above problem (A copy of dll's in both the base AND plugins directories - causing our application not to start.

@kellcomnet2
Copy link

I have this need as well with another plugin architecture, the code has to use the existing copy of the dll on the end pc but to develop against it I import the reference then set copy local to false.

@jnm2
Copy link

jnm2 commented Nov 24, 2017

I ran into this too. Right now I'm dealing with it by including this .targets:

<Project>

  <Target Name="PreventFooSDKCopyLocal" AfterTargets="ResolveReferences">
    <ItemGroup>
      <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' == 'Foo.SDK.PackageId'" />
    </ItemGroup>
  </Target>

</Project>

@jnm2
Copy link

jnm2 commented Dec 28, 2017

Fails miserably in projects that use packages.config, though. There is still a reason to use packages.config in projects that use this SDK package, sadly, because VS2012 is the latest version of Visual Studio that doesn't crash when using the designer with controls that use the legacy security policy (see https://stackoverflow.com/questions/20978721/visual-studio-2013-crashes-with-netfx40-legacysecuritypolicy-dynamic-operation).

Anyone know of a way to cause <Reference> elements added to legacy csproj while installing a NuGet package to have Private="False"?

@teocomi
Copy link

teocomi commented Mar 27, 2018

I'm encountering this issue too, especially when creating VSIX templates for software addins/plugins. CopyLocal needs to be set to False.

@simplicbe
Copy link

We use our own application to find those issues during building (Jenkins): https://github.com/simplic/simplic-package-version-check

@ajwaka
Copy link

ajwaka commented Nov 28, 2018

We too need this feature.

We develop modules/plugins/etc for other software. We must reference a core version of the framework - but may be using a newer version of the site. Upon build - we push our dll to the local website and work. If I'm running version 8.0.4 of a site - but I can support back to a 7.0.2 -- then I reference the 7.0.2 version. But upon adding the reference - the 7.0.2 get's pushed to the site and breaks my site.

Tedious especially when there's related references needed in having to track everything down. Just add the reference and don't push it to the output folder. Copy Local = False if I need/want it.

@donker
Copy link

donker commented Feb 7, 2019

The "DNN Platform" is a .net CMS which is distributed with a bunch of dlls. If you create an extension you need to reference one or more of these dlls. But you should not include them in packaging and if you compile debug to a live site, you should not copy them over. It is important developers can target an older framework than the one they may be developing in to increase compatibility. In short: we also need this feature.

@y325A
Copy link

y325A commented Mar 26, 2019

If anyone is still following this thread... this solution worked for me: PowerShell/PowerShellStandard#35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests