C# 使用dotnet pack创建包含外部.exe文件的NuGet包
编辑:我是如何解决这个问题的: 使用以下nuspec创建了一个新的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
<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>