编辑:我为解决此问题所做的工作:
使用以下 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>
将所有 .exe 文件放在该文件夹中。
现在从我的 ImageOptimizer 我使用以下代码:
var userProfileDir = System.Environment.GetEnvironmentVariable("USERPROFILE");
string pathVips = Path.Combine(userProfileDir, Constants.VipsDir, "vips.exe");
一些背景
我目前正在开发一个图像处理库,该库需要使用名为 VIPS 的外部工具将图像从 JPEG 转换为 PNG。 (https://github.com/jcupitt/libvips)。
因为我不想在我自己的项目中包含来自 VIPS 的二进制文件,所以我想,让我们为它制作一个 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>
我编辑了我的 .csproj 文件,使其只包含以下内容:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
<Version>1.0.4.0</Version>
</PropertyGroup>
</Project>
问题
每当我现在运行“dotnet pack”命令时,一切似乎都很顺利:
但是 VIPS 目录中的所有文件都没有包含在我创建的 nupkg 中:
(我选择工具的原因是因为在早期版本的 dotnet 框架/NuGet 中,我使用了像 ILRepack 这样的工具,它会自动安装在一个 tools 目录中,然后可以从你部署的 .exe 文件的相对路径中调用它).
(另请参阅第 92 行 https://github.com/gluck/il-repack/blob/master/build.gradle 中的 nuspec 代码,其中它们还在“工具”目标中包含创建的 .exe 文件)
进一步调查
然后我尝试将 VIPS 目录中的所有文件添加到我的 csproj 文件中,并将构建操作设置为 Content。
所有二进制文件现在都包含在以下 2 个目录中(所以所有重复项也很奇怪): vipsnuget.1.0.0.nupkg\content\VIPS\ vipsnuget.1.0.0.nupkg\contentFiles\any\netstandard1.0\VIPS\
但是,当我现在将 NuGet 包包含在另一个项目中,然后打包该项目时,它似乎也再次包含该包中的所有二进制文件:
(所有 VIPS 二进制文件现在都放在:DeveImageOptimizer.1.0.0.nupkg\contentFiles\any\netstandard1.5\和 content\VIPS 中)
这并不是真正可取的,因为其中的 DLL 的实际大小应该只有几 Kb。
这种方法的另一个问题
我实际上不确定是否有好的/更好的解决方案,但目前,当恢复 NuGet 包时,它将被提取到 %userprofile%.nuget\packages\vipsnuget...
因此,每当我想对 VIPS.exe 运行命令时,我需要将 Process.Start 参数指向 %userprofile%...。有一个更好的方法吗? (比如在代码中找到还原NuGet包的地方?)
我最想要的
基本上我最想要的是创建一个 NuGet 包,如果您包含它,某个目录将被复制到项目的构建输出中。
所以像这样: DeveImageOptimizer\bin\debug\VIPS...
如果不存在
如果没有办法做到这一点,我想听听将某些“工具”放入 NuGet 包并从 C# 代码内部调用它们的正常方法是什么。
最佳答案
当您不带任何参数调用 dotnet pack
时,它会使用当前文件夹中的 .csproj
文件创建 nuget 包并忽略任何 .nuspec
文件。如果查看 dotnet pack
参数,您将找不到如何直接指定 .nuspec
。
但是,dotnet-pack文档说我们可以为打包过程的 dotnet pack 命令提供 MSBuild 属性。来自 NuGet metadata properties :
NuspecFile
Relative or absolute path to the .nuspec file being used for packing. Note
If the .nuspec file is specified, it's used exclusively for packaging information and any information in the projects is not used.
NuspecBasePath
Base path for the .nuspec file.
因此,通过添加以下内容来修改您的 .csproj
<PropertyGroup>
<NuspecFile>location to your nuspec file</NuspecFile>
</PropertyGroup>
注意:您始终可以直接使用 nuget pack
命令。
关于c# - 使用 dotnet pack 创建带有外部 .exe 文件的 NuGet 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45269270/