-
Notifications
You must be signed in to change notification settings - Fork 252
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
Provide an option to hide content files from project tree in new-style csproj #4856
Comments
See also #4166 which may be related. |
I think there's a slightly broader question here to consider as well - if contentFiles do appear, how should they show up in the project tree? One possible option (my preference) would be to have them appear underneath the Dependencies -> NuGet node in the project (show the .cs files directly underneath the name of the package that includes them). There may be other/better options as well. Having the ability to show these files is nice for setting breakpoints, but IMO we should have something better than just dumping everything in the project root. |
I'm currently using the following workaround (thanks to @emgarten for the idea):
|
Here's a fairly simple option that might improve things: <Compile Include="$(NuGetPackageRoot){package ID}\{package version}\contentFiles\cs\net45\{relative path}" Condition="Exists('$(NuGetPackageRoot){package ID}\{package version}\contentFiles\cs\net45\{relative path}')">
<NuGetPackageId>{package ID}</NuGetPackageId>
<NuGetPackageVersion>{package version}</NuGetPackageVersion>
<NuGetItemType>Compile</NuGetItemType>
<Private>False</Private>
<Link>{relative path}</Link>
</Compile> Note that the link item just has the relative path of the cs file. Add some prefix to the link item, such as "NuGetContent{package Id}": <Link>NuGetContent\{package Id}\{relative path}</Link> Unfortunately, I think this approach would only work item types like Compile that aren't binplaced; items that are copied to the output directory would get messed up if they have some kind of prefix added to them, because it would affect the output path. |
The idea of the prefix was inspired by this technique from the pre-NuGet 3 days: Though I'd suggest omitting the version from the path as only one version of a package can be installed anyway (and making the path longer might contribute to MAX_PATH issues; not sure if that matters in a Link though). |
Actually it looks like there's a more fundamental problem here and something like the NuGetContent approach mentioned above is essential to correct behavior, due to collisions with multiple packages using the same file name. See #5048 for details. |
I'm using the above workaround like so: <Compile Update="@(Compile)">
<Link Condition="'%(NuGetPackageId)' != ''">%(NuGetPackageId)\%(Link)</Link>
</Compile> This serves two purposes:
This should imo be the default. |
What is the state of this issue? |
I did and changed it to "Content", but it does not get rid of folders for me. |
Are the above workarounds supposed to work for dependencies of a referenced nuget package? They don't seem to. For example, I am referencing the CefSharp.Common package which has a dependency on CefSharp.Redist.x64 which has a bunch of compiled C++ libs that are to be pulled into the bin folder upon building, but are also showing up in the root of my project structure in Solution Explorer, and cannot figure out how to make those go away. |
For reference the |
Copying my proposal from dotnet/project-system#6290 (comment) Whether a file is "visible" or not shouldn't even be a responsibility of the package/library maker. Some users of those packages might decide they want to display, some might not. So there should be an option to show/hide this on a per-project basis. Look at dotnet/project-system#3302 for an idea of the mess it can be. I have to scroll down more than 60 items before seeing the first class of my project. So here is a proposal: <PackageReference Include="ThirdParty" Version="1.0">
<ContentFilter Include="*.config" Visible="False" />
<ContentFilter Include="*.dll" Visible="False" />
</PackageReference> Note that this proposal is compatible with the above proposal to show those files under the package node. |
I think making contentFiles visible by default under the dependency node makes the most sense. |
if I cant change them or use them, I dont want to see them. I've finally been more or less coerced into using package reference style of nuget after holding out with packages.config for as long as I could (3+ years) and yet there are still these obvious, productivity crippling bugs with package reference. How much time does this cost users trying to navigate project structure to "just deal with it", and how much time is it costing for those who tried to troubleshoot before they find this issue report? It cost me few hours already and is still accruing. |
Any update on this? Navigating a project like this is pretty awful: Adding '<Visible>False</Visible>' to the content item does not seem to do anything (this is what the MSTest package also does, but doesn't have any effect in the solution explorer) |
@kzu how embarrassing... I totally missed that. |
Even so, they aren't part of the project. You can't do anything with them except be confused by them. |
4 years later, any progress on this one, please? |
I still waiting for this |
This is what worked for me, I used Nuget Package Explorer (NPE) but this should work with other packers as well. Create a new nuget package in NPE. Add a folder "contentFiles" and "Build". In the "contentFiles" folder add a folder "any" and inside that another folder "any." (The any any has to do with the target build, if it does not matter any any is safest). Add all unmanaged DLLs/files in this inner most folder. Edit the metadata source code (.nuspec file) so that it looks like this: <?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Example.Code</id>
<version>1.0.0</version>
<title></title>
<authors>Me</authors>
<owners>Me</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Description</description>
<contentFiles>
<files include="any\any\File1.dll" buildAction="None" copyToOutput="true" flatten="false" />
<files include="any\any\File2.txt" buildAction="None" copyToOutput="true" flatten="false" />
</contentFiles>
</metadata>
</package> Where all unmanaged files are listed in the content file section. If build action is needed that can be set, make sure copyToOutput is set to True, and flatten can be set to false unless folder structure must be retained. In the "Build" folder you will need to add a .props file with the same name as your project. The .props file should be set up as following: <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="File1.dll">
<Visible>false</Visible>
</None>
<None Include="File2.txt">
<Visible>false</Visible>
</None>
</ItemGroup>
</Project> Where again you list every file. The Visible false tag will keep these from showing up in the solution explorer in Visual studio. If the build action for a file is not None in the .nuspec file then you may have to use a Compile instead of None ItemGroup. |
Thanks for .props file <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Update="@(None)">
<Visible Condition="'%(NuGetItemType)' == 'None' and '%(NuGetPackageId)' == 'My.Package.Id'">False</Visible>
</None>
<Compile Update="@(Compile)">
<Visible Condition="'%(NuGetItemType)' == 'Compile' and '%(NuGetPackageId)' == 'My.Package.Id'">False</Visible>
</Compile>
</ItemGroup>
</Project> |
Now this method will work to add unmanaged files to the bin directory only on project build. If you are sending the executable of your project somewhere else additional steps will be required. The .nuspec file can stay the same with None items for each required file but the items must be EmbeddedResource in the .props file. When you add the nuget file to a project this will add the unmanaged files as an embedded resource for the project. Now before calling these unmanaged DLLs they must be copied to the bin directory. I do this using a constructor on the containing class. Example is in C#:
Note that the IO operations performed here are not thread safe. This will try to write the embedded files to the output directory every time a new instance of the containing class is created. To save time during execution I also check to see if the files already exist and if they do I don't write over them. |
6 years later, any progress on this one, please? |
you can done it with .props file |
This ensures the instrumentation scripts are not visible users projects when they reference `OpenTelemetry.AutoInstrumentation`. This makes the manual installation route slightly less unobtrusive as we don't clutter anyones editor with instrumentation.sh and instrumentation.cmd. These files will still be published to output and publish directories. The props file is only necessary until NuGet/Home#4856 gets resolved. See: https://learn.microsoft.com/en-us/nuget/concepts/msbuild-props-and-targets for more background on how $PROJECT.props file affect nuget installations.
Ensure contentFiles are unobtrusive in code editors This ensures the instrumentation scripts are not visible users projects when they reference `OpenTelemetry.AutoInstrumentation`. This makes the manual installation route slightly less unobtrusive as we don't clutter anyones editor with instrumentation.sh and instrumentation.cmd. These files will still be published to output and publish directories. The props file is only necessary until NuGet/Home#4856 gets resolved. See: https://learn.microsoft.com/en-us/nuget/concepts/msbuild-props-and-targets for more background on how $PROJECT.props file affect nuget installations.
In my case, after installing a NuGet package ( I was able to hide them via:
|
I'm currently using VS 2015 with project.json with a number of sources-style NuGet packages (packages that only have contentFiles with c# code as *.cs files).
There are quite a few files that come in this way, so having them not show up in the project root is key. When I try migrating to the new-style csproj, that's what happens, so I'm currently blocked (stuck back in project.json-style NuGet).
Two possible solutions here (I'm sure there are others as well):
If there's a workaround I could use at the moment (perhaps getting the files to appear somewhere nested under a project folder rather than showing up directly in the project root), that would be great to know as well. (Hopefully long-term there is a way to control where these files appear, unless the default changes back. Project root-only doesn't seem sufficient for a large number of content files.)
The text was updated successfully, but these errors were encountered: