Create NuGet package with external .exe files using dotnet package

Edit: what I did to solve this problem:

Created a new NuGet package with the following nuspec:

<package>
  <metadata>
    <id>VIPSNuget</id>
    <version>1.0.0.0</version>
    <title>$title$</title>
    <authors>Devedse</authors>
    <owners>Devedse</owners>
    <licenseUrl>https://github.com/jcupitt/libvips/blob/master/COPYING</licenseUrl>
    <projectUrl>https://github.com/jcupitt/libvips</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Just the EXE file for VIPS</description>
    <releaseNotes>First release</releaseNotes>
    <copyright>Copyright 2017</copyright>
    <tags>VIPS exe file</tags>
  </metadata>
  <files>
    <file src="VIPS\*.*" target="tools" />
  </files>
</package>

      

Placed all .exe files in this folder.

Now from my ImageOptimizer I am using the following code:

    var userProfileDir = System.Environment.GetEnvironmentVariable("USERPROFILE");
    string pathVips = Path.Combine(userProfileDir, Constants.VipsDir, "vips.exe");

      

A bit of background

I am currently working on an image processing library that is supposed to convert an image from JPEG to PNG using an external tool named VIPS. ( https://github.com/jcupitt/libvips ).

Since I didn't want to include the binaries from the VIPS in my own project, I thought to let it make a NuGet package where the .exe file from my code can be called.

The steps I took

I am creating a new dotnet networking solution using the "dotnet new console" command. After that I created a directory called "VIPS" and inserted all the executables there.

Then I created a nuspec file containing the following XML:

<?xml version="1.0"?>
<package>
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>$title$</title>
    <authors>Devedse</authors>
    <owners>Devedse</owners>
    <licenseUrl>https://github.com/jcupitt/libvips/blob/master/COPYING</licenseUrl>
    <projectUrl>https://github.com/jcupitt/libvips</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Just the EXE file for VIPS</description>
    <releaseNotes>First release</releaseNotes>
    <copyright>Copyright 2017</copyright>
    <tags>VIPS exe file</tags>
  </metadata>
  <files>
    <file src="VIPS\*.*" target="tools" />
  </files>
</package>

      

I edited the .csproj file to only contain this:

<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <TargetFramework>netstandard1.0</TargetFramework>
    <Version>1.0.4.0</Version>
  </PropertyGroup>    
</Project>

      

Problem

Whenever I run the "dotnet pack" command everything looks fine: NuGet package created

But all files from VIPS directory are not included in my created nupkg: No tool catalog

(The reason why I chose tools is because in earlier versions of the dotnet / NuGet platform I used tools like ILRepack, which will be automatically installed in the tools directory, which can then be called from the relative path of your deployed .exe file) ...

(Also see for example the nuspec code at https://github.com/gluck/il-repack/blob/master/build.gradle on line 92 where they also include the generated .exe file in the 'tools box)

Further research

What I was trying then was to add all files from VIPS directory to my csproj file and set build action to Content.

All binaries are now included in the following 2 directories (so all duplicates, which are weird as well): vipsnuget.1.0.0.nupkg \ Contents \ VIPS \ vipsnuget.1.0.0.nupkg \ contentFiles \ any \ netstandard1.0 \ VIPS \

However, when I now include a NuGet package inside another project and then package that project, it also includes all the binaries in that package as well:

Large file size

(All VIPS binaries are now placed inside: DeveImageOptimizer.1.0.0.nupkg \ contentFiles \ any \ netstandard1.5 \ and again in content \ VIPS)

This is not very desirable since the actual size of the DLL there should only be a few kilobytes in size.

Another problem with this approach

I'm not really sure if there is a good / better solution for this, but currently, when a NuGet package is restored, it will be fetched to% userprofile% .nuget \ packages \ vipsnuget ...

So whenever I want to run a command against VIPS.exe, I need to point the Process.Start arguments to% userprofile% .... Is there a better way to do this? (For example, find the place where NuGet packages are restored in code?)

What i like the most

Basically what I like the most is the need to create a NuGet package where if you include it, a specific directory will be copied to the project build output.

So something like: DeveImageOptimizer \ Bin \ Debug \ VIPs ...

If it doesn't exist

If there is no way to do this, I would like to hear what would be the normal approach to install certain "tools" inside a NuGet package and call them from C # code.

+3


source to share


1 answer


When called dotnet pack

without any arguments, it uses the file .csproj

in the current folder to build the nuget package and ignores any files .nuspec

. And if you look into the parameters dotnet pack

, you won't find how to specify directly .nuspec

.

But the dotnet-pack docs says that we can provide MSBuild properties to the dotnet pack command for the packaging process. From NuGet Metadata Properties :

NuspecFile

The relative or absolute path to the .nuspec file used for packaging. Note

If a .nuspec file is specified, it is used exclusively for packaging information and any information is not used in projects.

NuspecBasePath

Base path for the .nuspec file.



So, change yours .csproj

by adding the following

<PropertyGroup>
  <NuspecFile>location to your nuspec file</NuspecFile>
</PropertyGroup>

      

Note: you can always use the command nuget pack

.

+1


source







All Articles