23

I'm trying to use PhantomJS NuGet package in .NET core csproj application. But I think it is not possible using new PackageReference syntax for NuGet.

When I reference the PhantomJS package like this:

<PackageReference Include="PhantomJS" Version="2.1.1">
  <IncludeAssets>all</IncludeAssets>
</PackageReference>

It does not do anything when I run dotnet build.

I'd expect it to copy the files inside PhantomJS package to the output directory (or anywhere in the project) so I could use the binary file provided by the PhantomJS package.

Is there another way to copy the contents of PhantomJS NuGet package to the output directory with MSBuild?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Ciantic
  • 6,064
  • 4
  • 54
  • 49

7 Answers7

18

I think you want to use:

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

in the main <PropertyGroup>, which causes all dependencies to be copied to the output folder. This means every single dependency gets copied though so this can be quite a mess in some situations.

If you then want to exclude specific assemblies or packages:

<ItemGroup>
    <-- won't copy to output folder -->
    <PackageReference Include="MahApps.Metro" version="1.6.5">
      <IncludeAssets>compile</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Dragablz" version="0.0.3.203">
      <IncludeAssets>compile</IncludeAssets>
    </PackageReference>
    ... 

    <-- normal will copy to output folder -->
    <PackageReference Include="xmlrpcnet" version="3.0.0.266" />
    <PackageReference Include="YamlDotNet" version="6.0.0" />
</ItemGroup>


<ItemGroup>
    <!-- keep assembly reference from copying to output -->
    <Reference Include="$(SolutionDir)MarkdownMonster\bin\$(Configuration)\$(TargetFramework)\MarkdownMonster.exe">
      <Private>false</Private>
    </Reference> 
</ItemGroup>

compile in this context means they are available for compilation, but aren't copied to the output folder.

Rick Strahl
  • 17,302
  • 14
  • 89
  • 134
  • 1
    I noticed it had to be in its own `PropertyGroup` like so: ` true ` – LosManos Dec 05 '21 at 20:28
  • 2
    No that isn't right @LosManos. If you have multiple groups they are all agregated into a single group. Order might matter though so you may want to move the directive to the end of the section. – Rick Strahl Jan 01 '23 at 01:03
17

There are two solutions:

1:

  <ItemGroup>
    <PackageReference Include="PhantomJS" Version="1.0.8" GeneratePathProperty="true" />
  </ItemGroup>

  <Target Name="CopyPdfExe" AfterTargets="Build">
    <Copy SourceFiles="$(PkgPhantomJS)\tools\phantomjs\phantomjs.exe" DestinationFolder="$(OutDir)" />
  </Target>

2:

  <ItemGroup>
    <PackageReference Include="PhantomJS" Version="1.0.8" GeneratePathProperty="true" />
  </ItemGroup>

  <ItemGroup>
    <None Include="$(PkgPhantomJS)\tools\phantomjs\phantomjs.exe" CopyToOutputDirectory="PreserveNewest" />
  </ItemGroup>

prefer the #2 since if this project is referenced by another one, the .exe can also be copied to the output folder

iownbey
  • 69
  • 5
Jiayin Pei
  • 355
  • 2
  • 9
  • Thank you. Used method #2 - works like a charm. This allowed me to fix explicitly one legacy nuget after migrating csproj to PackageReference. I really appreciate such local and explicit approach, – mikka Jan 19 '23 at 13:39
2

The <PackageReference> syntax in NuGet uses transitive dependencies, just like the project.json syntax. As such, the same rules apply. See this NuGet v3 which talks about what does and doesn't work between packages.config and the newer syntax. Specifically

You cannot rely on install.ps1 or uninstall.ps1 to function. These files will execute when using packages.config, but will be ignored in v3. So your package needs to be usable without them running. Init.ps1 will still run on NuGet 3.

To get files to copy to the output directory, the PhantomJS NuGet package needs to be changed to use contentFiles.

Eric Erhardt
  • 2,286
  • 15
  • 19
  • 1
    Thanks. I think that is really unfortunate, [I've opened a bug report](https://github.com/NuGet/Home/issues/4837). I think it's not realistic to expect all packages to change their nuspec, it would be better if PackageReference had a feature to copy given directories or files e.g. to output directory. I'll keep this still open, there are various tricks in msbuild that could allow to do this anyway. – Ciantic Mar 17 '17 at 19:51
  • 2
    Anyone have an example nuspec file of how to use contentFiles? – Jason Rowe Mar 31 '17 at 14:30
  • 3
    Here's an example from MSBuild's repo: https://github.com/Microsoft/msbuild/blob/6851538897f5d7b08024a6d8435bc44be5869e53/build/NuGetPackages/Microsoft.Build.Runtime.nuspec#L30-L32 – Eric Erhardt Mar 31 '17 at 23:35
  • 1
    Thanks that gets the files into bin folder when running dotnet build. A small step forward. – Jason Rowe Apr 03 '17 at 13:57
2

The tag names are misleading. Try

<PackageReference Include="PhantomJS" Version="2.1.1">
  <IncludeAssets>none</IncludeAssets>
</PackageReference>

or

<PackageReference Include="PhantomJS" Version="2.1.1">
  <ExcludeAssets>all</ExcludeAssets>
</PackageReference>

instead in order to get the referenced assemblies and other files copied to the build output. See https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files

abatishchev
  • 98,240
  • 88
  • 296
  • 433
JSpot
  • 450
  • 4
  • 12
1

Try dotnet publish

dotnet publish [<PROJECT>] [-c|--configuration] [-f|--framework] [--force] [--manifest] [--no-dependencies] [--no-restore] [-o|--output] [-r|--runtime] [--self-contained] [-v|--verbosity] [--version-suffix]
dotnet publish [-h|--help]

See https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore2x

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
Bella Li
  • 21
  • 1
0

I know this is an old question, but what worked for me was to set IncludeAssets to "runtime"

Frank Hagenson
  • 953
  • 8
  • 17
0

Actually what is claimed to not work in the original question is what worked for me in .NET6:

<PackageReference Include="PhantomJS" Version="2.1.1">
  <IncludeAssets>all</IncludeAssets>
</PackageReference>
knocte
  • 16,941
  • 11
  • 79
  • 125