NuGet Restore Fails when dependency adds a .targets import to the .csproj - nuget

I ran into an issue recently with NuGet restore. I added a project dependency (in this case PostSharp) and then enabled restore. I checked in the source, but not the /packages directory (as I shouldn't needed to....right!). When TeamCity or another developer grabs the source and runs MsBuild, they receive the following error:
C:\TeamCity\buildAgent\work\e374975c0264c72e\ProjectName\ProjectName.csproj(70, 3): error MSB4019: The imported project "C:\TeamCity\buildAgent\work\e374975c0264c72e\packages\PostSharp.2.1.5.1\tools\PostSharp.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
The problem is, NuGet hasn't run yet to restore/download PostSharp or it's .targets file. This feels like a NuGet bug to me, but wanted to see if others have this same issue.
Anybody have this issue or know the resolution. Yes, I could check-in the /packages directory, but then why use NuGet at all?

Another approach is to modify the <Import> element in question, to make it conditional, e.g.:
<Import Project="$(CodeAssassinTargets)" Condition="Exists($(CodeAssassinTargets))" />
This depends on a new property defined in an earlier <PropertyGroup>. I usually add one at the top of csproj file with other "global" flags, e.g.:
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CodeAssassinTargets>$(SolutionDir)packages\CodeAssassin.ConfigTransform.1.1\tools\CodeAssassin.ConfigTransform.targets</CodeAssassinTargets>
<AutoParameterizationWebConfigConnectionStrings>false</AutoParameterizationWebConfigConnectionStrings>
<UseMsdeployExe>true</UseMsdeployExe>
</PropertyGroup>
Then in an appropriate target, like BeforeBuild, give a helpful error message:
<Target Name="BeforeBuild">
<Error Text="CodeAssassin.ConfigTransforms target is missing. It needs to exist at $(CodeAssassinTargets) in order to build this project!" Condition="!Exists($(CodeAssassinTargets))" />
</Target>
With these modifications, the project will load even if the nuget package restore has never been done. If auto package restore is enabled, the first build attempt should clear up the missing target issue, but if it does not, one manual package restore will.

#porterhouse91, have you checked your csproj file to make sure it has been set up with the appropriate build target?
I haven't yet tried the new built-in Package Restore feature, but I'm assuming it works at least somewhat like the previous workflows out there on the interwebs. If that's the case, enabling Package Restore in your solution only affects the projects in your solution at the time you enable it. If you've added a new project (having NuGet dependencies) to the solution since enabling Package Restore, you're gonna need to enable it again.
Another possibility: the previous workflows involved having a .nuget folder that you needed to check in to VCS, so you might need to check that in if it hasn't been checked in yet (if the built-in Package Restore feature does indeed use this approach).
BTW, if this answer is at all helpful, thank Stephen Ritchie -- he asked me to give it a shot for you.

I had a problem like this as well, but I was able to modify the .targets file in the source package to work around it. Basically, RestorePackages is a build target that runs when the project is built. Unfortunately, the package won't even load properly before the imports are satisfied. The only way I know to fix this is to include the .targets file as content and then change the BuildDependsOn property so it restores the packages before it runs your custom tasks.
<PropertyGroup>
<BuildDependsOn Condition="$(BuildDependsOn.Contains('RestorePackages'))">
RestorePackages;
CustomTarget;
$(BuildDependsOn);
</BuildDependsOn>
<BuildDependsOn Condition="!$(BuildDependsOn.Contains('RestorePackages'))">
CustomTarget;
$(BuildDependsOn);
</BuildDependsOn>
</PropertyGroup>
To be clear, this doesn't help with pre-built packages, but if you can build the package again yourself, you can fix it.

I ran into this same issue with Visual Studio 2012 and NuGet packages not checked into source control.
The error:
The imported project "\packages\Microsoft.Bcl.Build.1.0.7\tools\Microsoft.Bcl.Build.targets" was not found.
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
I found a msdn writeup on the situation that gave the following workarounds for grabbing a project from source control without the NuGet packages.
Stop using package restore and check-in all package files
Explicitly run package restore before building the project
Check-in the .targets files
I decided to go with option #2, however, NuGet currently (v2.6) does not include a way to install all packges from the packages.config file from within visual studio. Some searching revealed that you need to use the NuGet Command Line to execute the following command before opening Visual Studio (reference).
c:\path\to\nuget.exe install -o packages project-folder\packages.config

Related

.NET 5 "Could not find a part of the path"

I cloned .NET 5 project, which should be working (unfortunately, I can't provide the project so you could reproduce the problem). I didn't change anything, I just wanted to build it, however, I am getting this error when restoring packages (although the project itself is on different disk, I found out that this is "global-packages" folder):
Could not find a part of the path 'C:\Users\me\.nuget\packages\microsoft.aspnetcore.azureappservices.siteextension\5.0.5\content\store\x64\net5.0\microsoft.extensions.configuration.environmentvariables\5.0.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.EnvironmentVariables.dll'
However, I don't think it is a problem with this particular dll, as my colleague cloned the same project and he is getting the same error, but with different library.
This is what I've already tried doing:
Clearing all nuget cache
Checking "automatically check for missing packages during build in visual studio"
Updating everything I could (VS, nuget..)
Running VS as Administrator
Checking package sources (yes, nuget.org is there)
Adding "add key="repositoryPath" value="$..\..\packages"" into the nuget.config file - this didn't actually create the package folder in the defined path
Clean/rebuild/... everything
I think, that the problem will be in some setting, but I have no idea, where to look :/
Use the command dotnet restore
instead of
dotnet nuget

How to execute custom script when installing nuget package?

I created this project https://github.com/RemiBou/RemiBou.CosmosDB.Migration, for working it needs the user to do 2 things : create the appropriate folders and edit the csproj so the file inside those folders are embedded.
Before we could do that automaticly when installing with install.ps1 but this feature has been deprecated. Do you know any way how I could do this ?
install.ps1 isn't exactly deprecated, but it's a feature unique to packages.config. PackageReference has no concept of install as anyone can simply edit the csproj and add a PackageReference. When you restore, NuGet has no way of knowing if this is the first time the package is restored for the project after the reference was added, or if it's just the first time the project was restored with a clean repo (after a "msbuild /t:clean" or "git clone", for example).
I don't know an alternative for creating the folders other than having documentation that says the convention is to use that folder name. But, an alternative to modifying the csproj is to take advantage of the fact that MSBuild is a generic build system and NuGet packages can include MSBuild props and targets file.
In your specific case, I would create a props file that defines a property something like <RemiBouCosmosDBMigrationPath>CosmosDB\Migrations\</RemiBouCosmosDBMigrationPath>, which allows your package users to change the property to a different path be overwriting the property value in their csproj, if they prefer.
Then create a targets file which contains a target something like
<Target name="RemiBouCosmosDBMigrationsEmbedMigrations" BeforeTargets="???">
<ItemGroup>
<EmbeddedResource Include="$(RemiBouCosmosDBMigrationPath)**\*.js" />
</ItemGroup>
</Target>
You'll need to figure out what the best target name to put in the BeforeTargets attribute, but I hope you understand the idea. A csproj file is nothing more than a MSBuild file with certain conventions. MSBuild files can import other MSBuild files, and MSBuild and NuGet work together to allow MSBuild to import MSBuild files that come from restored packages. Just compose the MSBuild properties and items in a different way, and the end result can still be the same.

Use solution relative packages folder with NuGet and project.json

I have a solution with a packages folder checked into source control. I changed some of the projects to use a project.json file rather than packages.config for defining dependencies. The projects are all normal .csproj projects, not DNX .xproj projects. Everything seemed to be working correctly however after updating a package I noticed that the new version wasn't added to the solution's packages folder. Instead it was added to NuGet's new shared packages folder in the user profile folder.
So the question is, how do I get NuGet to use the solution's packages folder rather than the shared folder?
Approaches I've tried so far without success:
Adding global.json file in the solution folder specifying "packages": "packages"
Setting <add key="disableSourceControlIntegration" value="false" /> in .nuget\nuget.config
NuGet 3.2 added support for specifying the shared global packages folder using an environment variable, NUGET_PACKAGES. You can set the full path to an alternative global packages folder, however I discovered that if you simply set the variable to "packages" then the NuGet tools in Visual Studio will treat it as a relative path under your solution folder. That allowed me to install and restore NuGet packages using the solution's packages folder.
Unfortunately building projects then gave me errors in Microsoft.NuGet.targets, unable to locate NuGet packages. The NugetPackagesDirectory property in msbuild doesn't seem to getting set. To work around this I added the following lines in to the C:\Program Files (x86)\MSBuild\Microsoft\NuGet\Microsoft.NuGet.props file:
<PropertyGroup Condition="'$(NugetPackagesDirectory)' == ''">
<NugetPackagesDirectory>$(SolutionDir)packages</NugetPackagesDirectory>
</PropertyGroup>
This will affect all solutions on the machine so an alternative would be to add those same lines in each project file or into a custom props file in the solution which you import into each project. This may also be needed for build servers too.
Although this works, the drawback is that the packages folder has a different structure, packages\<package_name>\<version>\ compared to packages\<package_name>.<version>\, and old or unused versions of packages aren't deleted after they're updated or uninstalled. Manually clearing the packages directory and then restoring required packages after any changes will achieve the same thing.
Personally this feels really hacky as it requires setting global settings for something which should be set on a per solution basis. NuGet is going to be updated at some point to support per solution package directories with project.json but in the meantime this you can use the above work around, or just stick with packages.config for the time being.

NuGet Package Restore doesn't work

I have added a NuGet package to my solution and enabled package restore on the solution. This correctly created the .nuget folder with targets file etc.
The NuGet package is actually another project which becomes a dependency in the solution. Initially I added this package to the solution manually.
To Test this NuGet feature, I deleted the folder underneath the packages folder.
At that point I then get compiler errors obviously because other dependent projects are reliant on the project that has just been removed.
When I build the solution, I'm expecting NuGet to go and download the NuGet packages that it requires is this is set to Enable Package Restore, and then build successfully as all other dependent projects can now build.
However, I see no evidence of the NuGet package from being downloaded in the output, and the build errors remain the same as if the project hasn't been downloaded.
Can anyone confirm whether there is something I am missing or am doing wrong here?
To my knowledge deleting packages under the packages folder should be restored by NuGet's package restore feature.
It would be helpful to:
See the actual build error.
Know which packages you are trying to restore.
Some packages, such as ours, rely on .targets files which have issues when being used in package restore.
Make sure that NuGet.Config in your solution folder has "packageRestore" option enabled:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageRestore>
<add key="enabled" value="True" />
</packageRestore>
</configuration>
Also it should be enabled globally in "C:\Users\%UserName%\Application Data\NuGet\NuGet.Config" (it can be set from within VS, Tools->Options->Package Manager.
Also note that there's another approach for restoring package since NuGet 2.7 - "Automatic Package Restore". See doc for more info: http://docs.nuget.org/docs/reference/package-restore and http://docs.nuget.org/docs/workflows/migrating-to-automatic-package-restore

NuGet package files not being copied to project content during build

I am building an MVC4 web application with VS2012 professional with NuGet Package Manager version 2.2.31210. I have multiple projects in my solution, all sharing various packages I installed using NuGet. One of my projects is an MVC4 web application where I am using packages such as bootstrap, jquery UI, etc, all installed using NuGet.
When I clone a fresh copy of my entire solution from my repository and build my MVC4 project, the package restore feature seems to be working: it creates the packages directory under the solution direcotry and populates it will all the versions of the packages I expect to see. However, the content files do not get copied to the appropriate places in the MVC app directory. The weird thing is that it does create directories for the content, but does not copy the content files themselves.
For example, I am using the Twitter Bootstrap package which appears in the packages/Twitter.Bootstrap.2.2.2. In the MVC project a directory called bootstrap (containing css, img, and js directories) gets created in the Content directory. But, no css or js files are copied into those directories!
Does anyone have a clue what magic incantation I must utter to get the build to copy these content files from the NuGet packages directory?
This is a very common issue we are all having. I've created an MSBuild Task NugetContentRestoreTask that will do this trick for you. Run the following command in the Package Manager Console:
Install Nuget Content Restore MSBuild Targets
PM> Install-Package MSBuild.NugetContentRestore
The only thing left is to call it from your BeforeBuild Target with something like this:
Project File Targets
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)" />
</Target>
You can take a look at the source repo and find it on nuget.org
Additional Content Folders
This nuget only includes the default folders scripts, images, fonts, and content, it is not a recursive directory includes. For additional content subfolders - you must assign the property AdditionalFolders.
<Target Name="BeforeBuild">
<NugetContentRestoreTask SolutionDir="$(SolutionDir)" ProjectDir="$(ProjectDir)"
AdditionalFolders="less;sass;common" />
</Target>
I have found a workaround, but it is ugly. By executing the following command in the NuGet Package Manager Console: Update-Package -Reinstall all the files are indeed copied to their proper places within the Mvc project Content and Scripts directories.
Unfortunately, this is risky because you are likely to end up with the wrong versions of certain packages. For example, in my case after the command finishes executing (which takes quite a while by the way), I end up with jQuery version 1.4.4. This is way old, and I assume it must be an explicit dependency of some other package that is being updated. So it appears that the order in which the packages actually get updated by NuGet is significant (it does not appear to parse the entire dependency tree for all packages and pick only the latest versions from the union of all dependencies, which seems like it would be the preferred behavior). Rather, as the command executes I see it replacing the jQuery package several times with different versions as it works its way through all the packages and their dependencies, only to end up with a very old version.
A similar approach is the execute the Update-Package -Reinstall command explicitly for each package that is causing my problem, but this is incredibly tedious and error prone.
The NuGet Package Restore feature should yield the same result as manually executing the Install-Package or Update-Package -Reinstall command for a package, but it does not.
I don't like to have the thirdparty JavaScript files under source control either. Thats why I've followed Jeff Handley advice in http://nuget.codeplex.com/workitem/2094 to create a solution my self. I didn't go the executable way, but created a nuget solution level package which does the trick.
http://www.nuget.org/packages/Baseclass.Contrib.Nuget.GitIgnoreContent/
It's tied to git, as it automatically updates the .gitignore file.
Short description:
Ignore nuget content files in git:
Generate entries in the .gitignore file to exclude nuget content files from the source repository
Restore nuget content files before building (Automatically in VS and manually with a powershell script
I've written a blog post describing how to use it.
http://www.baseclass.ch/blog/Lists/Beitraege/Post.aspx?ID=9&mobile=0
In Visual Studio 2015 Update 1, they now support contentFiles. The caveat with this is that it only works in projects that use project.json.
In reference to the problem that you are having, there is a good blog post that explains why you see this behaviour: NuGet Package Restore Common Misconceptions.
For my projects it turned out that content files work with PackageReferences only:
Existing project with nuget references via packages.config
Installed NuGet package with content files
Build project
No content files in output directory
Conversion of packages.config to PackageReferences
Build project
Content files have been copied to output directory
IDE is Visual Studio 2017. The project is an application project which means it is in the old csproj format.