vaibhav
vaibhav

Reputation: 116

Importing props or targets from nugets in msbuild

I'm importing a props file from a nuget using PackageReference. Working with this using commandline is not an issue since msbuild /t:restore can parse the project files and it ignores missing files. msbuild /t:build then has valid paths to work with courtesy of restore.

Visual Studio however fails to load any project containing such import since it determines that to be an invalid csproj. How can I make Visual Studio ignore this import for loading?

Note that if I were to use msbuild /t:restore first from commandline(so that XXX.csproj.nuget.g.props and XXX.csproj.nuget.g.targets are generated), Visual Studio can load the project fine. I want to avoid such a dependency.

Import snippet:

<ItemGroup>
    <PackageReference Include="ScopedManifest.Task" GeneratePathProperty="true" />
</ItemGroup>
<Import Project="$(Pkg_ScopedManifest_Task)\include\ScopedManifestTask.Props" />

Error when loading project in VS:

error : The imported project "D:\include\ScopedManifestTask.Props" was not found. Confirm that the expression in the Import declaration "\include\ScopedManifestTask.Props" is correct, and that the file exists on disk. D:\work\test-build\repo\src\Manifest\Manifest.csproj

Upvotes: 2

Views: 9358

Answers (2)

Mr Qian
Mr Qian

Reputation: 23808

First, I wonder if this nuget package is created by yourself and it seems that you want to import a props file into nuget package. But I found you used Include node which is not the correct way to realize it.

Please try to use Build node rather than Include node and name the custom targets as <package_id>.targets, then pack your nuget project.

In fact, when your nuget package contains such <package_id>.targets file, it will be automatically embedded in the new project when the nuget package is installed. More info you can refer to this document.

This means that the file has an important role for the nuget package, and there are additional auxiliary operations during the nuget package installation process, so the file cannot be easily removed. That is the MSBuild props and targets working mechanism. See this link.

So you cannot avoid using this file in projects and you should add it back.

Suggestion

1) For new sdk format projects, this node is imported in project folder\obj\xxx.csproj.nuget.g.props.

enter image description here

First,make sure that the xxx.targets file exists in the nuget package.

Then check whether the import path is correct under that path both on xxx.csporj and xxx.csproj.nuget.g.props.

I think your import path is different in the xxx.csproj.nuget.g.props which is generated automatically at build time. That is the address automatically captured by the nuget mechanism. You need to check and keep it consistent. You can delete the bin and obj folder and then rebuild your project to test it again.

If it is not consistent, maybe you need to recreate this nuget package in an official way

2) If your nuget package is broken and you should delete it under global nuget caches and restore it again.

-- clean nuget caches first or delete all files under C:\Users\xxx(current user)\.nuget\packages

-- delete bin, obj folder and any custom import node in xxx.csporj file

-- do restore operation and then rebuild your project to test again.

Upvotes: 1

riQQ
riQQ

Reputation: 12823

Use a condition. That's also the way it's done when you add a NuGet package containing props or targets to your project in Visual Studio.

<Import Project="$(Pkg_ScopedManifest_Task)\include\ScopedManifestTask.Props" Condition="Exists('$(Pkg_ScopedManifest_Task)\include\ScopedManifestTask.Props')" />

Nuget also adds this so you get a build error on a missing import:

<Project>
...
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('$(Pkg_ScopedManifest_Task)\include\ScopedManifestTask.Props')" Text="$([System.String]::Format('$(ErrorText)', '$(Pkg_ScopedManifest_Task)\include\ScopedManifestTask.Props'))" />
  </Target>
...
</Project>

Upvotes: 4

Related Questions