7

Desired output

We want to distribute a .dll (NetStandard project) and some files through the NuGet package installation. When installing it in a Xamarin.Android project:

  • A file (Directory.Buil.props) is copied to the solution folder
  • An executable (config.exe) is copied to the project folder
  • A directory (Files) and its contents are copied in the project folder

Problems

  • Projects using PackageReference will not get the files copied (content not supported)
  • For some reason, when using a .nuspec file; source files, obj, bin etc. are packed too

Solution

Ideally, we would like to:

  • only use a .csproj file (without .nuspec)
  • not have both content and contentFiles packed in the .nupkg
  • easily access the .dll from the .csproj
  • when installing a newer .nupkg version, old files will be overwritten

Questions

(1) Is this doable with PackageReference and contentFiles ?

(2) What's the best approach you can think of ?

Thanks.

Responses

Leo:

When installing the package in an Android project, the files don't appear in the project. Not to mention that the files are just referenced and not copied (even if I had copyToOutput="true"):

Solution projects after NuGet package installation

Leo (edit):

I cannot use the new SDK csproj format. Taken from your link:

Disclaimer: this only works for a small set of project types.

  • class library projects
  • console apps
  • ASP.NET Core web apps
  • .NET Core

If you are building ASP.NET 4 (i.e not ASP.NET Core), WPF, Universal Windows, or Xamarin projects, you’ll have to stick with the old format

JonZarate
  • 841
  • 6
  • 28

1 Answers1

0

(1) Is this doable with PackageReference and contentFiles ?

I am afraid you could not add those files to the Android project, but I would like provide an alternative solution here, add those files to the output folder.

You could use PackageReference and contentFiles directly for the latter two requirements, config.exe and Files. But for the first requirement Directory.Buil.props, we need do more things, since it is copied to the solution folder rather than project folder.

For the latter two requirements, config.exe and Files, we could use .nuspec file with contentFiles to including them, need set copyToOutput="true", like:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
  <metadata>
    <id>MyTestCore</id>
    <version>4.0.0</version>
    <authors>TestContentFile</authors>
    <owners>TestContentFile</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package Description</description>
    <contentFiles>
      <files include="any/any/config.exe" buildAction="content" flatten="true" copyToOutput="true"/>
      <files include="any/any/Files/1.txt" buildAction="content" flatten="true" copyToOutput="true"/>
      <files include="any/any/Files/2.txt" buildAction="content" flatten="true" copyToOutput="true"/>
    </contentFiles>
  </metadata>

  <files>
    <file src="contentFiles/any/any/config.exe" target="contentFiles/any/any/config.exe" />
    <file src="contentFiles/any/any/Files/1.txt" target="contentFiles/any/any/Files" />
    <file src="contentFiles/any/any/Files/2.txt" target="contentFiles/any/any/Files" />
  </files>
</package>

After packing this .nuspec and install the generated package to the project.

However, we could not find those files under the References node. That because the project still use the old csproj with packagereference not using the new sdk csproj.

Old csproj to new csproj: Visual Studio 2017 upgrade guide

Besides, copying files into the project's source directory is not supported and has been a discouraged practice for classic projects. The contentFiles section controls the msbuild items that are generated for these files into the obj\projectname.csproj.nuget.g.props file. And check the project.assets.json file you can find:

  "targets": {
    "MonoAndroid,Version=v7.1": {
      "MyTestCore/5.0.0": {
        "type": "package",
        "contentFiles": {
          "contentFiles/any/any/Files/1.txt": {
            "buildAction": "Content",
            "codeLanguage": "any",
            "copyToOutput": true,
            "outputPath": "1.txt"
          },
          "contentFiles/any/any/Files/2.txt": {
            "buildAction": "Content",
            "codeLanguage": "any",
            "copyToOutput": true,
            "outputPath": "2.txt"
          },
          "contentFiles/any/any/config.exe": {
            "buildAction": "Content",
            "codeLanguage": "any",
            "copyToOutput": true,
            "outputPath": "config.exe"
          }
        }

See: nuspec contentFiles not added to a project

Then we need build this project, those files will copied to the output folder.

For the first requirement, in order to add the Directory.Buil.props to the solution folder, we need create a custom copy target in the YourPackageName.targets file, then add this .targets file into the \build folder, the .targets file looks like:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <ItemGroup>  
        <MySourceFiles Include="<FilePath>\Directory.Buil.props"/>  
    </ItemGroup>  

    <Target Name="CopyFiles" BeforeTargets="Build">  
        <Copy  
            SourceFiles="@(MySourceFiles)"  
            DestinationFolder="<SolutionFolder>"  
        />  
    </Target>  

</Project>

The .nuspec file like:

  <files>
    <file src="<>\xxx.targets" target="build" />
  </files>

Hope this helps.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • 2
    This isn't working on an Android project. I added an edit with the results. – JonZarate Jun 19 '18 at 10:26
  • 2
    @JonZarate, That is my fault. I forgot test it with Android project, just test it with `PackageReference`. I have updated my answer with more info, you can check the **However...** pieces for details. Hope this can give some helps :) . – Leo Liu Jun 20 '18 at 06:48
  • 2
    I added another response. Have you tested this before posting ? – JonZarate Jun 20 '18 at 08:48
  • 2
    @JonZarate, Yes, I have test it. Have you seen the word "we could not find those files under the References node." and "those files will copied to the output folder."? Do you want add those files to the project under the References node? If yes, I afraid I could not give other useful help :(. – Leo Liu Jun 20 '18 at 08:55
  • 2
    I guess I am missing some steps then. Could you upload the solution and link it ? – JonZarate Jun 20 '18 at 09:17
  • The solution: https://1drv.ms/u/s!Ai1sp_yvodHf2S8UfYEi1QfQ2pb5 And the test nuget package: https://1drv.ms/u/s!Ai1sp_yvodHf2TCEl2mY1dt0dyDN – Leo Liu Jun 20 '18 at 09:37
  • I just tested it, it's not working. When I install your `MyTestCore.nupkg` package in the `TestAppSample.Android` project, the files are not copied in the project folder. – JonZarate Jun 20 '18 at 09:58
  • Have you built your project? Those file will be copied to the output folder **NOT** project folder after you build your project. – Leo Liu Jun 20 '18 at 22:56
  • I know, but I didn't ask to copy the files to the *output* folder, I asked to `Copy files to Android project on NuGet installation`. You answered `The answer is yes.` and provided a solution, now I am telling you that it's not fulfilling the initial requirement. Thanks anyway! – JonZarate Jun 21 '18 at 08:56
  • Please, edit your answer. It's fine if you want to provide an alternative solution, but don't claim to answer my question. It is misleading for other readers. – JonZarate Jun 26 '18 at 12:57
  • 1
    @JonZarate, Yes, you are right. I have not noticed that. I accept your advice. I have update my answer, you can check it. Thanks for the suggestion :). – Leo Liu Jun 26 '18 at 17:41