C# 使用dotnet pack创建包含外部.exe文件的NuGet包

C# 使用dotnet pack创建包含外部.exe文件的NuGet包,c#,nuget,.net-core,C#,Nuget,.net Core,编辑:我是如何解决这个问题的: 使用以下nuspec创建了一个新的NuGet包: <package> <metadata> <id>VIPSNuget</id> <version>1.0.0.0</version> <title>$title$</title> <authors>Devedse</authors> <owners

编辑:我是如何解决这个问题的:

使用以下nuspec创建了一个新的NuGet包:

<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>
一些背景

我目前正在开发一个图像处理库,需要使用名为VIPS的外部工具将图像从JPEG转换为PNG。()

因为我不想在我自己的项目中包含来自VIP的二进制文件,所以我想,让我们制作一个NuGet包,从我的代码中可以调用.exe文件

我采取的步骤

我使用'dotnet new console'命令创建了一个新的dotnet核心解决方案。之后,我创建了一个名为“VIPS”的目录,并将所有二进制文件粘贴到其中

然后,我创建了一个包含以下XML的nuspec文件:

<?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>

$id$
$version$
$title$

但是VIPS目录中的所有文件都不包括在我创建的nupkg中:

(我之所以选择工具,是因为在dotnet framework/NuGet的早期版本中,我使用了ILRepack等工具,这些工具将自动安装在工具目录中,然后可以从部署的.exe文件的相对路径调用该目录)

(另请参见第92行中的nuspec代码,其中还包括“工具”目标中创建的.exe文件)

进一步调查

然后我尝试将VIPS目录中的所有文件添加到我的csproj文件中,并将构建操作设置为Content

所有二进制文件现在都包含在以下2个目录中(因此所有重复的文件也很奇怪): vipsnuget.1.0.0.nupkg\content\VIPS\ vipsnuget.1.0.0.nupkg\contentFiles\any\netstandard1.0\VIPS\

但是,当我现在在另一个项目中包含NuGet包,然后打包该项目时,它似乎也再次包含该包中的所有二进制文件:

(所有VIP二进制文件现在都放在:DeveImageOptimizer.1.0.0.nupkg\contentFiles\any\netstandard1.5\中,然后再放在content\VIPS中)

这并不是真正需要的,因为DLL的实际大小应该只有几个Kb

这种方法的另一个问题

实际上,我不确定是否有一个好的/更好的解决方案,但目前,当还原NuGet包时,它将在%userprofile%.NuGet\packages\vipsnuget中提取

因此,每当我想对VIPS.exe运行命令时,我都需要将进程指向%userprofile%。有更好的方法吗?(例如,找到在代码中还原NuGet包的位置?)

我最想要的

基本上,我最希望的是创建一个NuGet包,如果包含它,某个目录将被复制到项目的构建输出中

比如: DeveImageOptimizer\bin\debug\VIPS

如果不存在


如果没有办法做到这一点,我想听听将某些“工具”放入NuGet包中并从C代码内部调用它们的正常方法是什么。

当您在没有任何参数的情况下调用
dotnet pack
时,它使用当前文件夹中的
.csproj
文件创建nuget包并忽略任何
.nuspec
文件。如果查看
dotnetpack
参数,您将无法找到如何直接指定
.nuspec

但是,docs说我们可以为打包过程的dotnetpack命令提供MSBuild属性。发件人:

NuspecFile

用于打包的.nuspec文件的相对或绝对路径。 注

如果指定了.nuspec文件,则它仅用于打包 不使用项目中的信息和任何信息

NuspecBasePath

.nuspec文件的基本路径

因此,通过添加以下内容来修改
.csproj

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

nuspec文件的位置

注意:您始终可以直接使用
nuget-pack
命令。

这确实解决了我在未包含工具时遇到的问题:)。但是,我现在如何调用VIPS.exe文件?我真的应该在Users\..…\.nuget目录中调用它吗?或者我可以把它复制到我程序的输出目录吗?@Devedse查看。其主要思想是使用
CopyToOutputDirectory
标志,因此,您是否必须使用Copy Local将所有DLL/EXE文件包含在csproj文件中,或者也可以在nuspec文件中执行此操作?而且,看起来我实际上需要将文件添加为“内容”而不是“工具”(从链接的帖子中读取)。如果我这样做,所有的文件不会被添加到NuGet包中两次吗?(就像我第一次尝试的情况一样)?@Devedse-如果你问了一个单独的问题,请在这里发布链接。如果你没有找到合适的答案,我有一个解决方案。
<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <TargetFramework>netstandard1.0</TargetFramework>
    <Version>1.0.4.0</Version>
  </PropertyGroup>    
</Project>
<PropertyGroup>
  <NuspecFile>location to your nuspec file</NuspecFile>
</PropertyGroup>