Visual Studio 2017 csproj adds "weird" files on package install - c#

I have some issues with my VS2017 csproj's(https://natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/). When I install certain nuget packages, I'd get some additional files being added to my project and most of the time the dependency is not even working properly. It does not do that on older csproj's.
Two examples:
I have one "home made" nuget (made out of a VS2017 csproj too) which is supposed to transform the local app.config of the target project on install and uninstall (basically adding a line on install and removing it on uninstlal). On a older csproj, it does what it needs to do. With a VS2017 csproj, it will not do the transform but add the two transform files to the projects.
I need to install the package named "CefSharp.OffScreen" on one of my projects. On an older one it works like a charm. On a VS2017 csproj the dependency is not even there (it has a "!" in front) and it adds two "x64" and "x86" directories with tons of files ("dll's" etc.) in there.
Is there something known about issues like that with VS2017 projects ?
Thanks in advance for the help !

Is there something known about issues like that with VS2017 projects ?
For the first example, That because xdt transforms aren't supported in PackageReference environment. This includes both sdk-based projects as well as classic .net framework projects using PackageReference instead of packages.config. You can follow this GitHub issue for more details. There is also a sample package that shows how to use build-time logic to apply transforms instead to work in all environments.
For the second example, you can find a CefSharp.Common.targets file in the \build folder in the dependency package CefSharp.Common, in this .target file, you can see following code:
<ItemGroup>
<CefSharpCommonBinaries32 Include="$(MSBuildThisFileDirectory)..\CefSharp\x86\*.*" />
<CefSharpCommonBinaries64 Include="$(MSBuildThisFileDirectory)..\CefSharp\x64\*.*" />
<CefSharpCommonBinariesAnyCPU Include="$(MSBuildThisFileDirectory)..\CefSharp\**\*.*" />
</ItemGroup>
With this .target file, nuget will including files under the x64 and x86 folder to your project.
In the old .csproj project, that .target file imported by following code after install the nuget packages, you can check it in your project file .csproj:
<Import Project="..\packages\CefSharp.Common.63.0.3\build\CefSharp.Common.targets" Condition="Exists('..\packages\CefSharp.Common.63.0.3\build\CefSharp.Common.targets')" />
Those files under the x86 and x64 folder would be imported when the project is running.
When you use the new .csproj project, the .target file imported by the file project.assets.json, all the files will be imported to the project when you save the .target in the project.assets.json.
That is the reason why you got those tons of dll files after install the package package CefSharp.Common. So, this is not a issue, but because they import .targets in different ways.
If you do not want show those dll files in your project, you can return back the packages.config.
Hope this helps.

Related

Shipping msbuild task as nuget

I need your help.
I'm developing an msbuild task that performs certain actions upon msbuild.
I want my users to be able to download and install a nuget package and once the package is installed the build task will be part of the build process.
I know how to release a nuget package and i know how to includes a custom targets file together with the nuget, what i don't know is how to add the import statement to the csproj upon nuget installation:
Is there a way to do so or am i asking for too much?
Thanx!
Gilad
The docs aren't in the easiest to find place, but here's a link to the docs on including MSBuild props/targets files in your package.
Basically, you put the file in the package in the location build\<tfm>\<package_id>.props. For example build\netstandard2.0\MyPackage.props. If you want your build targets to be included in all TFMs, you can use build\<package_id>.props, but if your package also contains other assets like lib/ or contentFiles/, the "no-TFM" build files will cause "asset-target fallback" to fail, so if your package has only net472 libs, and the build files, a project targeting netcoreapp3.0 will get only the build assets, none of the net472 assets. If your build files are in a TFM folder, then NuGet's asset target fallback will select both the lib and build assets. So, I strongly encourage everyone to always use the TFM folder.
The docs need to be improved, but the table explaining lists build, buildTransitive, and buildMultiTargeting. Projects using packages.config only use build assets under build. Projects using PackageReference only use build and buildMultiTargeting assets when the project references the package directly. Assets under buildTransitive get selected when the package is pulled in transitively, rather than directly. The difference between build and buildMultiTargeting is complex. If you understand the concept of "inner-build" and "outer-build" in multi-targeting SDK style projects, that's the difference (build is inner-build), otherwise only use build.
I should update the docs to have this information.

Does nuget create separate packages?

I am still confused about how nuget works. I git clone a C# .sln project and from console, and I ran this nuget command:
nuget restore my_project.sln
it came to my attention that it generates two packages containing all dependencies required by my_project.
One package is located under my_project/src/packages, the other c:/users/my_user_name/.nuget/packages. While the file structures are a little different the DLL files in both packages are identical.
That confused me. Why two packages are generated by default? Where exactly does Visual studio look up for the project's dependencies?
More important, which config file should I update in order to only keep a copy of the dependencies and how can I specify the location in my file system for the packages?
Recent versions of NuGet support package references in project files.
This format will restore packages on demand, using your %USERPROFILE%.nuget folder as a cache. And your solution folder won't be "polluted" by a packages folder with binaries that you probably don't want to commit to source control.
VS2017 allows you to select "PackageReferences" or the older "Packages.Config" format when you create new projects (Tools/Options/NuGetPackageManager/General).
You probably have some projects in your solution that use the older "Packages.config" format, which stores in the packages folder in the solution directory, and newer "PackageReferences" format.
To convert the older projects to the new format, I believe you need to remove all packages from the project, then add them back again. They will be added using the default format you selected, with a prompt for confirmation if you selected "Allow format selection on first package install".

Visual studio won't read .pdb from my nupkg

I have generated some nuget packages containing .pdbs with the following:
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
I have verified the .pdbs are within the .nupkg generated in the lib/*/ folder next to the dll's.
However, when I consume these nuget packages in Visual Studio 2017, it only extracts the .dll's and not the .pdb's. Leaving me unable to debug into the package.
What am I doing incorrectly?
Since you can make sure the .nupkg contains the .pdb file. please make sure both the projects are in debug mode.
Consuming a nuget package locally sometimes has some difference from installing it from nuget.org. The .pdb source won't be found in solution. By default, the .pdb will locate under path like :C:\Users\xxx\.nuget\packages\PackageName\xxx.
Update:
If the nuget package project and the project which consumes it is on the same machine. The AllowedOutputExtensionsInPackageBuildOutputFolder property is enough. Since you have source files on same machine, and the debug engine can easily find it so that you can step into it.
But if for a scenario like this: You developed the nuget package. And share it to other team members. To make them can Step into you should embed the xx.cs files into the .nupkg.
Under this circumstances, the AllowedOutputExtensionsInPackageBuildOutputFolder may not work. I can't find a way to embed source files using it. You may need to use a nuget pack command like this issue. Actually, the way Stephan packed the project is correct. I've checked it work and will embed the source files and .dll and .pdb into the .nupkg. Of course, in this way you need to add the path to source files repo by Solution=>Properties=>Debug Source files:
In addition: You can add the nuget pack command in a post-build event, so that every time you build a project successfully, it will package for you.
Also, you can consider source links as source control so that you won't configure the source path by Solution=>properties.

Adding a NuGet package to packages.config not associated with a Visual Studio project

In the limited amount of time I've worked with NuGet, the packages.config files I've encountered have all been associated with a Visual Studio project. I've just found one that seems to not be associated with a project (in this case a C# project). Rather, it's purpose appears to be to gather tools that are required to successfully complete a build of the solution the project is a component of (i.e. the NuGet packages in the packages.config file are never referenced directly in a .cs file).
I know I can open the packages.config in a text editor and add a new package to it. However, that seems to run contrary to the idea of NuGet as I understand it, and I'm not sure if adding an entry into packages.config manually won't create problems down the road.
What is the best way to add a new NuGet package to a packages.config file that's not associated with a Visual Studio project like this? The Microsoft docs I've found so far all seem to mention a corresponding VS project ( see https://learn.microsoft.com/en-us/nuget/consume-packages/ways-to-install-a-package)
Using Visual Studio to manage NuGet references for .NET projects that use packages.config is useful/important because of all the extra things that need to happen on "install". But for .NET projects that use PackageReference, using Visual Studio is just a minor convenience because it will restore the packages at the same time as changing the XML. There is no Visual Studio UI for isolated packages.config files
So, there's no problems editing your packages.config file with a text editor. You'll just need to run nuget.exe restore yourself (or more likely it's part of a build script). In fact, the NuGet team have one themselves as part of their build.

Unnecessary folders from NuGet packages

My c# app target framework is 4.6.2
I downloaded from NuGet some packages, my question:
when I open my app in file explorer, under packages\somepackage\lib I have this:
do I really need net 40 and net45 folders?
can I delete that? how do I know what is unnecessary?
Reason why NuGet keep the folders
Nuget uses two different methods to manage packages of every project:
packages.config
PackageReference
packages.config is only used for old project files which cannot import and reference NuGet packages automatically. NuGet will change the *.csproj file to add the references. Because it changes the code which is under version control and cannot use an absolute path, so it should put the NuGet package cache folders in every solution. In this case, NuGet might have the ability to remove the useless folders. But this is the behavior of legacy NuGet version (version 2.x). NuGet doesn't want to fix a legacy behavior.
PackageReference is the new behavior of NuGet references. NuGet put all the NuGet cache in a common folder so that it will not take too much disk space by the same NuGet packages. In this case, NuGet doesn't know every lib version on your whole computer projects, so it can't remove the useless version folders.
Conclusion: NuGet doesn't know whether it is safe to remove them in PacakgeReference and doesn't want to remove them in packages.config.
Upgrade packages.config to PackageReference
UPDATE:
From VisualStudio 2017 version 15.7 there is an integrated feature that allows you to do this upgrade without using third party tools Migrate from packages.config to PackageReference
In Solution Explorer, right-click on the References node or the packages.config file and select Migrate packages.config to PackageReference...
You can try a Visual Studio extension NuGet PackageReference Upgrader to upgrade your packages.config to PackageReference so that it will not store libs in every solution folders to eat up your disk space.
P.s.
NuGet take me nearly 10GB on my C:\ .

Categories

Resources