获取NuGet包目录的位置

5
我正在创建一个 NuGet 包,希望确保在所有情况下都能正常工作。在这种情况下,我正在使用 "Build" 惯例文件夹添加构建目标。我正在添加的目标需要知道 NuGet 包文件夹的位置。很多示例都假设可以使用 "..\Packages",但是 NuGet 允许您通过 nuget.config 文件重新定位包文件夹。是否有一种方法可以从 build.targets 文件中获取正确的 NuGet 包文件夹位置?
(背景信息)
我正在编写一个需要将本地 dll 复制到 bin 目录的包。我可以使用后期生成事件,但那似乎有点 hacky。我宁愿包含一个目标,来调用 msbuild 的 任务,SkipUnchangedFiles=true,但为了使其工作,我需要知道包文件夹的位置。
4个回答

13

通过 $(MSBuildThisFileDirectory) 属性,您可以从 .targets 文件中访问当前文件的位置。

假设 .targets 文件位于 nuget 构建文件夹中,则可以使用相对路径访问其自己的包文件夹,例如:

<PropertyGroup>
    <ThisPackageDirectory>$(MSBuildThisFileDirectory)..\</ThisPackageDirectory>
    ...

1
虽然被接受的答案解决了根本问题,但这个答案回答了标题中的问题(获取NuGet包目录的位置)。 - Yodan Tauber

5
为了解决您在背景信息部分描述的问题,您需要进行以下两个步骤:
A. 确保将本地动态链接库复制到项目中——编辑 nuspec 的一个部分,当构建包时将文件复制到项目根目录中:
<?xml version="1.0"?>
<package>
  <metadata>
    ...
  </metadata>
  <files>
    <file src="install.ps1" target="Tools"/>
    <file src="nativedll1.dll" target="content" />
    <file src="nativedll2.dll" target="content" />
  </files>
</package>

B. 创建一个 install.ps1 文件(注意我已经将它包含在上面的示例中)。

您的 install.ps1 文件应该像这样:

param($installPath, $toolsPath, $package, $project)

$file1 = $project.ProjectItems.Item("nativedll1.dll")
$file2 = $project.ProjectItems.Item("nativedll2.dll")

# set 'Copy To Output Directory' to 'Copy if newer'
$copyToOutput1 = $file1.Properties.Item("CopyToOutputDirectory")
$copyToOutput1.Value = 2

$copyToOutput2 = $file2.Properties.Item("CopyToOutputDirectory")
$copyToOutput2.Value = 2

这些.dll文件会像这样被添加为引用吗? - Tony
2
不,这些是本地dll,所以OP希望将它们视为内容。如果您想将一些xml文件或图像复制到bin文件夹中,则可以采用此方法。 - CarllDev
感谢澄清。我已经读了5遍,但还是没理解。 - Tony
接受为答案。我真的希望有一种方法可以发现包目录的位置,因为这样我就可以利用包恢复功能,而不必将dll添加到项目中(和分布式源代码控制),但这也可以运行。 - JMarsch

1
为什么不创建一个自定义的MsBuild任务,将nuget.config文件作为XDocument加载,并获取element的值?

如果必要的话,我可以自己构建,但我真正想要的是一个预先构建好的方法来完成这个问题。我只是想确认在我投入工作之前是否需要手动构建一些东西。加载nuget配置足够简单,但nuget配置在目录结构的几个级别上“级联”,因此正确地执行并不像听起来那么容易。但你是对的--如果没有内置的方法来完成它,我将不得不自己构建。 - JMarsch

1
在 install.ps1 文件中,$installPath 变量给出了安装目录的位置 - 您只需要进入其父目录即可:
$packagesFolder = (get-item $installPath).parent.FullName

这与我最终如何实现它有关。我使用了你上面提供的方法,但我想在构建时而不是在包安装时获取该属性。我最终做了与SQL Server Compact Edition非常相似的事情--我使用NuGet来编写一个后期构建事件脚本,将dll从包位置复制到bin文件夹中。只要每个人都有相同的软件包位置,这将起作用--因为我只能在包安装时而不是在构建时发现位置。谢谢,+1。 - JMarsch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接