M.Y. Babt
M.Y. Babt

Reputation: 2891

Creating .nupkg from .csproj file in Visual Studio 2017: Properties not updated correctly

I use Visual Studio 2017, MSBuild version 15.4.8.50001.

I want to create a .nupkg file by reading directly from my .csproj file. Following the instructions here, I updated the first PropertyGroup in my .csproj file to this:

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{24BAFE05-8B92-4EAA-8790-03C0768ACC57}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>D</RootNamespace>
    <AssemblyName>D</AssemblyName>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <PackageId>MyCompany.Nuget.D</PackageId>
    <PackageVersion>1.0</PackageVersion>
    <Author>Me</Author>
    <Title>Nuget Experiment Project D</Title>
    <Description>Top-level class in the diamond dependency structure</Description>
  </PropertyGroup>

I opened the command prompt, navigated to the folder containing my .csproj file, and ran the command nuget spec, as documented here.

However, the resulting .nuspec file looks like this:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>$description$</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2017</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>
</package>

As you can see, none of the properties I defined in my .csproj file are correctly populated in my .nuspec file.

What am I doing wrong?

EDIT: I initially accepted this answer, but now I don't think it is correct.

I changed the PackageVersion property in my .csproj file to 2.0:

<PackageVersion>2.0</PackageVersion>

If, as the answer claims, the properties in .nuspec are indeed updated during packing by reading from my .csproj file, the new .nupkg file should have the name MyCompany.Nuget.D.2.0.0.nupkg.

However, the new .nupkg file is still named D.1.0.0.nupkg:

enter image description here

EDIT: I followed the instructions included in Leo-MSFT's answer, and changed the AssemblyInfo.cs file to the following:

[assembly: AssemblyTitle("NewD")]
[assembly: AssemblyDescription("Some dummy description")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("MyCompany.Me")]
[assembly: AssemblyProduct("NewD")]
[assembly: AssemblyCopyright("Copyright MyCompany 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("3.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

According to this page, $id$ is retrieved from the AssemblyName field in my .csproj file, and $version$, $author$, $description$ and $copyright$ are retrieved from AssemblyInfo.cs. For that reason, I also updated the AssemblyName field in my .csproj file to MyCompany.NugetTest.D.

I navigated to the folder containing my .sln file, and ran nuget spec "D\D.csproj" as suggested in the answer. The generatednuspec`` file looked like this:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>D\D.csproj</id>
    <version>1.0.0</version>
    <authors>Me</authors>
    <owners>Me</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package description</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2017</copyright>
    <tags>Tag1 Tag2</tags>
    <dependencies>
      <dependency id="SampleDependency" version="1.0" />
    </dependencies>
  </metadata>
</package>

I changed id to SuperUniqueD, and ran nuget pack D.csproj. The package D.3.0.0.nupkg was then created.

Why is the package still named D? Shouldn't it be named MyCompany.NugetTest.D if the value is read from the AssemblyName field in the .csproj file (according to documentation), or NewD if it is read from AssemblyInfo.cs?

Upvotes: 3

Views: 3138

Answers (3)

Leo Liu
Leo Liu

Reputation: 76720

none of the properties I defined in my .csproj file are correctly populated in my .nuspec file. What am I doing wrong?

That because you navigated to the folder containing your .csproj file, you should navigate to the folder containing your .sln file or include full path in your command without navigation, the command like:

  1. Navigate to solution folder:

    C:\Workspaces\NuGet Experimentation\D>nuget spec "D\D.csproj"

  2. Without navigation:

    C:\Users\Admin>nuget spec "C:\Workspaces\NuGet Experimentation\D\D\D.csproj"

The tokens in the form $<token>$ are be replaced during the packaging process with values from the project's Properties/AssemblyInfo.cs file. The settings info of this file are included in the .sln file. If you navigate to the folder containing your .csproj file, NuGet could not find the location of AssemblyInfo.cs, so NuGet will use the default value $<token>$ instead of the value from the AssemblyInfo.cs file. Using above methods, you will get the .nuspec file like:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>C:\Workspaces\NuGet Experimentation\D\D\D.csproj</id>
    <version>1.0.0</version>
    <authors>Admin</authors>
    <owners>Admin</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package description</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2017</copyright>
    <tags>Tag1 Tag2</tags>
    <dependencies>
      <dependency id="SampleDependency" version="1.0" />
    </dependencies>
  </metadata>
</package>

In order to select a package ID that is unique across nuget.org, you also need to modify the Id of .nuspec manually. See Create the .nuspec package manifest file for more detail info.

For the Edit question:

However, the new .nupkg file is still named D.1.0.0.nupkg.

Just like answer the first question "The tokens in the form $$ are be replaced during the packaging process with values from the project's Properties/AssemblyInfo.cs file."

So if you want to generate the package with update version, you should update the Assembly Version in the AssemblyInfo.cs file, then use the pack cammand line to generate the nuget package: nuget pack xx.csproj.

See Replacement tokens for more info about tokens.

Update for Edit:

I changed id to SuperUniqueD, and ran nuget pack D.csproj. The package D.3.0.0.nupkg was then created.

Since you are using the command: nuget pack D.csproj, you should change the Id in your project file rather than .nuspec file:

enter image description here

If you changed the Id in the .nuspec, you should pack it with .nuspec file: nuget pack D.csproj.nuspec

Upvotes: 3

ThePretendProgrammer
ThePretendProgrammer

Reputation: 1517

The properties in the .nuspec file are indeed updated from your .csproj file properties. However, there is one exception in this case. When generating NuGet packages from projects, the version of the NuGet package corresponds to the Assembly Version. So, if within your project, you open the AssemblyInfo.cs file and update the Assembly Version to 2.0.0.0 from 1.0.0.0 and build the project, the resultant package that gets generated on nuspec pack will have the name with the version 2.0.0.

Upvotes: 0

Metehan Senol
Metehan Senol

Reputation: 669

I think this is correct nuspec properties.

This $id$ and other tokens are replaced with the values from the .csproj file at packing time.

Upvotes: -1

Related Questions