0

My project uses an executable called wkhtmltopdf that converts an HTML into a pdf. I've created a NuGet package that simply output the exe in the root of the project so that it can be referenced and used by my application.

If I install the nuget package everything works fine, meaning that the executable is added into my application and I can work with it.

The problem is that I don't want to commit the executable but I want that if another dev pull down my project and build it, the executable will be added to his project as well (without installing again the Nuget package).

I've tried by committing only the reference to the package

<package id="Wkhtmltopdf" version="0.12.5" targetFramework="net45">

but it didn't work.

The .nuspec file is very simple and contains only this line (besides the default ones)

...   
<files>
    <file src="wkhtmltopdf.exe" target="Content\wkhtmltopdf.exe" />
</files>
...

Any idea if what I'm asking is possible?

Sergio
  • 250
  • 1
  • 4
  • 18

2 Answers2

1

Yes, add the reference to the package to your packages.config, and enable NuGet Package Restore in your build pipeline. If you're using VSTS, that's a specific task in the build pipeline for new-style builds. If you're using Visual Studio, it's an option in the preferences (Tools -> Options -> NuGet Package Manager). For other build systems you can invoke nuget restore from the command line.

Matt Whitfield
  • 6,436
  • 3
  • 29
  • 44
  • Thanks but the option is already enabled. What is happening though is this: if I go to myProject/packages/wkhtmltopdf I can see the .nupkg and a Content folder with the executable. But this is not the folder I specified in the nuspec. When I install the nuget with the nuget manager the executable is added to the right location. – Sergio Jul 17 '18 at 21:46
  • You might want to look at tools packages. You can add a .targets file which can copy files to the bin folder or similar. It does sound, however, like package restore is doing what it should do and adding stuff to the 'packages' folder. – Matt Whitfield Jul 18 '18 at 00:09
  • Yes, package restore is doing the job but I would like to resolve the problem at the root. To be more precise consider a CI configuration using TeamCity. I have set up a build step to restore nuget packages using Nuget Installer runner type. I want during this step the content to be added in my root project. I'm also trying to figure out if I can run `Update-package "packageId"` command during the build but I don't think that's the way it works – Sergio Jul 18 '18 at 18:30
1

Any idea if what I'm asking is possible?

The reason for this issue is that you are target the file to the content in the .nuspec file target="Content\wkhtmltopdf.exe".

According the From a convention-based working directory:

enter image description here

We could to know file in the convention-based working directory content: Contents are copied to the project root.. It modified the project file.

When another dev pull down your project and build it, nuget will restore this package to \packages folder. However, NuGet does not modify your project, it just like download that package to the \packages folder not install this package to your project.

Check my previous thread for some more details.

That is the reason why you see the .nupkg and a Content folder with the executable in the \packages folder not in the project file folder, which is not the the right location where you want.

To resolve this issue, The easiest way is using the NuGet command line in the Package Manager Console:

Update-Package -reinstall

to force reinstall the package references into project after another dev pull down your project.

Of course, you can also resolve this issue from the root cause, just like matt comment, target your executable file to the Tools, like target="Tools\wkhtmltopdf.exe" and add a .targets file target to the \build, target="Build\NuGetPackageName.targets", to copy executable file to your project file. If you are interested in it or you have any issue about this, I would like share your some more details info about this.


Update:

Now I show you how to do it with Tools folder and .targets file.

This is my .nuspec file:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>MyToolPackage</id>
    <version>1.0.0</version>
    <authors>Tester</authors>
    <owners>Tester</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package description</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2018</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>

  <files>
    <file src="wkhtmltopdf.exe" target="Tools\wkhtmltopdf.exe" />
    <file src="MyToolPackage.targets" target="Build\MyToolPackage.targets" />
  </files>

</package>

Note: The name of your .targets file should be same as your package name, like, my package name is MyToolPackage, so the name of the .targets should be MyToolPackage.targets.

The content of the MyToolPackage.targets file:

<!--
***********************************************************************************************
Copy the wkhtmltopdf.exe to the bin folder of project.
***********************************************************************************************
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="CopyTool" BeforeTargets="Build">
    <Message Text="Copy tool to bin folder."></Message>
    <Copy
    SourceFiles="$(SolutionDir)packages\MyToolPackage.1.0.0\Tools\wkhtmltopdf.exe"
    DestinationFolder="$(ProjectDir)bin"
        />
  </Target>

</Project>

Pack this .nuspec file, you will get following package:

enter image description here

Then install this package to your project, when you build your project, Visual Studio will execute the copy task in the MyToolPackage.targets file before the start of the building, wkhtmltopdf.exe will be copied to the bin folder, of course, you can copy it to any other folder, just need to change the DestinationFolder in the MyToolPackage.targets file.

Hope this helps.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • Thanks for sharing your answer. Sorry but I'm a little bit confused. I don't understand exactly how Tools and Build folder work. Which one should I use? And how can I reference the .exe from my project once the package is installed? Just as a heads-up. My previous nuspec target was `` which added the .exe to the bin folder, but rebuilding the project delete the executable. – Sergio Jul 18 '18 at 15:25
  • So, following this [guide](https://docs.microsoft.com/en-us/nuget/create-packages/creating-a-package#including-msbuild-props-and-targets-in-a-package) I've created this .nuspec file `......` with the executable under the path `build\net462\wkhtmltopdf.props\wkhtmltopdf.exe`. Now I'm facing 2 problems: first, when installing the package in Visual Studio an error says: "[..] the package does not contain any assembly references or content files that are compatible with that framework [...]". 2nd, even if this work how will I reference the .exe inside my project? – Sergio Jul 18 '18 at 19:32
  • 1
    @Sergio, I have given you a detailed steps to resolve this issue, please check my UPDATE answer. If you have any other question, please let me know. – Leo Liu Jul 19 '18 at 02:01