使用.targets文件使用NuGet设置文件属性

Mat*_*t W 3 nuget nuget-spec nuget-package-restore visual-studio-2015

我正在构建一个要作为NuGet包安装的项目,我想设置SpecFlow功能文件的属性(因为它是最新的SpecFlow,不应该为这些功能生成代码隐藏文件.)

要实现选择文件的效果,打开它的属性窗格并设置几个值,我已经设置了我的项目结构:

\MyProject
  \build
    MyProject.targets
    \Framework <the folder containing the file I want to affect>
      FrameworkTests.feature <the file I want to affect>
  \Framework
    FrameworkTests.feature <the original location of the file I want to affect>
Run Code Online (Sandbox Code Playgroud)

我的.nuspec是这样的:

<?xml version="1.0"?>
<package >
  <metadata minClientVersion="2.5">
    <id>$id$</id>
    <version>$version$</version>
    ...
  </metadata>
  <files>
    <file src="build\MyProject.targets" target="build\MyProject.targets" />
    <file src="build\FrameworkTests\FrameworkTests.feature" target="build\Framework\FrameworkTests.feature" />
  </files>
</package>
Run Code Online (Sandbox Code Playgroud)

我的.targets文件是这样的:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <None Include="$(MSBuildThisFileDirectory)FrameworkTests\FrameworkTests.feature">
      <Link>FrameworkTests.feature</Link>
      <CopyToOutputDirectory>Copy if newer</CopyToOutputDirectory>
      <CustomToolNamespace></CustomToolNamespace>
    </None>
  </ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

我没有看到在安装软件包时将FrameworkTests.feature文件复制到项目中.我需要改变什么?

Leo*_*SFT 8

我没有看到在安装软件包时将FrameworkTests.feature文件复制到项目中.我需要改变什么?

这是nuget文件夹约定的默认行为.如果在文件content夹中设置文件,nuget会将这些内容复制到项目根目录,然后您将在解决方案资源管理器中看到它们.如果在build文件夹中设置文件,nuget会自动将它们插入到项目文件中,或者project.lock.json像项目文件中的以下脚本一样:

<Import Project="..\packages\MyProject.1.0.0\build\MyProject.targets" Condition="Exists('..\packages\MyProject.1.0.0\build\MyProject.targets')" />
Run Code Online (Sandbox Code Playgroud)

因此,FrameworkTests.feature除非您将文件夹更改为,否则这就是您无法在解决方案资源管理器中看到该文件的原因content.

您可以参考文档创建.nuspec文件以获取更多详细信息:

在此输入图像描述

此外,如果您将文件夹更改为内容,则.targets无效.因为当您将文件夹更改为内容时,在.targets文件中,您需要更改以下路径:

<None Include="$(MSBuildThisFileDirectory)FrameworkTests\FrameworkTests.feature">
Run Code Online (Sandbox Code Playgroud)

至:

<None Include="$(MSBuildThisFileDirectory)..\content\FrameworkTests\FrameworkTests.feature">
Run Code Online (Sandbox Code Playgroud)

但是MSBuild无法解析这条路径..\content.要解决此问题,我们需要将.targets文件更改为:

<None Include="$(ProjectDir)FrameworkTests.feature">
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用Install.ps1file 更改文件的属性,将其设置为nuget包.

有关详细信息,请参阅此主题.

更新:

我还应用了您所描述的更改,但仍无法更新CopyToOutputDirectory文件属性.

找到了.您需要更新两点,应该知道一点.

第一点:

我发现你的脚本如下.nuspec:

  <files>
    <file src="build\MyProject.targets" target="build\MyProject.targets" />
    <file src="build\FrameworkTests\FrameworkTests.feature" target="build\Framework\FrameworkTests.feature" />
  </files>
Run Code Online (Sandbox Code Playgroud)

注意:您可以设置你的目标文件夹build\Framework,但在你的.targets文件,你用它包括FrameworkTests;

<None Include="$(MSBuildThisFileDirectory)FrameworkTests\FrameworkTests.feature">
Run Code Online (Sandbox Code Playgroud)

所以,当把它改成内容文件夹时,你的.nuspec文件应该是:

  <files>
    <file src="build\MyProject.targets" target="build\MyProject.targets" />
    <file src="content\FrameworkTests\FrameworkTests.feature" target="content\FrameworkTests\FrameworkTests.feature" />
  </files>
Run Code Online (Sandbox Code Playgroud)

.targets文件应该是:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <None Include="$(ProjectDir)FrameworkTests\FrameworkTests.feature">
      <Link>FrameworkTests.feature</Link>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CustomToolNamespace></CustomToolNamespace>
    </None>
  </ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

第二点需要更新:

如果更新CopyToOutputDirectory,.targets文件中的值应为PreserveNewest Not Copy.

你需要知道的一点:

当您使用此方法更改其属性时FrameworkTests.feature,此文件的属性在解决方案资源管理器中不会更改,但是,MSBuild将在您构建项目时应用此更改.因为<Import Project="....\MyProject.targets" Condition="Exists('...')" />将在编译项目时进行解析.

因此,您可以CopyToOutputDirectory在构建项目后检查文件属性的输出(在构建项目之后,文件FrameworkTests.feature将被复制到输出文件夹.)

UPDATE2:

很多评论都传播说PowerShell脚本无法在构建服务器上运行,因为install命令不运行它们; 只有VisualStudio会

不确定PowerShell脚本无法在构建服务器上运行的所有原因,但绝大多数是因为PowerShell的默认安全级别.

尝试在PowerShell中输入:

set-executionpolicy remotesigned
Run Code Online (Sandbox Code Playgroud)

在Visual Studio 2015中,您需要安装Visual Studio 2015Windows Management Framework 4.0的扩展PowerShell工具.安装后,install.ps1将正常工作.以下是我的.nuspec文件和install.ps1个脚本.

.nu​​spec文件:

  <files>
    <file src="content\FrameworkTests\FrameworkTests.feature" target="content\FrameworkTests\FrameworkTests.feature" />
    <file src="scripts\Install.ps1" target="tools\Install.ps1" />
  </files>
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记删除MyProject.targets了在.nuspec文件中.

install.ps`1脚本:

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

function MarkDirectoryAsCopyToOutputRecursive($item)
{
    $item.ProjectItems | ForEach-Object { MarkFileASCopyToOutputDirectory($_) }
}

function MarkFileASCopyToOutputDirectory($item)
{
    Try
    {
        Write-Host Try set $item.Name
        $item.Properties.Item("CopyToOutputDirectory").Value = 2
    }
    Catch
    {
        Write-Host RecurseOn $item.Name
        MarkDirectoryAsCopyToOutputRecursive($item)
    }
}

#Now mark everything in the a directory as "Copy to newer"
MarkDirectoryAsCopyToOutputRecursive($project.ProjectItems.Item("FrameworkTests"))
Run Code Online (Sandbox Code Playgroud)

然后,在安装nuget包之后,FrameworkTests.feature文件的属性将更改为copy if newer:

在此输入图像描述

希望这可以帮助.


归档时间:

查看次数:

6293 次

最近记录:

6 年,7 月 前