我正在构建一个要作为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>
我的.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>
我的.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>
安装软件包时,我没有看到FrameworkTests.feature文件被复制到项目中。我需要改变什么?
答案 0 :(得分:7)
安装软件包时,我没有看到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')" />
因此,除非您将文件夹更改为FrameworkTests.feature
,否则这就是您无法在解决方案资源管理器中看到文件content
的原因。
您可以参考文档Creating the .nuspec file了解更多详情:
除外,如果您将文件夹更改为内容,.targets
将无效。因为当您将文件夹更改为内容时,在.targets
文件中,您需要更改以下路径:
<None Include="$(MSBuildThisFileDirectory)FrameworkTests\FrameworkTests.feature">
要:
<None Include="$(MSBuildThisFileDirectory)..\content\FrameworkTests\FrameworkTests.feature">
但MSBuild无法解析路径..\content
。要解决此问题,我们需要将.targets文件更改为:
<None Include="$(ProjectDir)FrameworkTests.feature">
或者,您可以使用Install.ps1
文件更改文件的属性,将其设置为nuget包。
有关详细信息,请参阅this thread。
<强>更新强>
我还应用了您所描述的更改,但仍然无法更新CopyToOutputDirectory文件属性。
找到它。有两点需要更新,一点应该知道。
第一点:
我在.nuspec
中找到了以下脚本:
<files>
<file src="build\MyProject.targets" target="build\MyProject.targets" />
<file src="build\FrameworkTests\FrameworkTests.feature" target="build\Framework\FrameworkTests.feature" />
</files>
注意:您为build\Framework
设置了目标文件夹,但是在.targets
文件中,您将其包含在FrameworkTests
;
<None Include="$(MSBuildThisFileDirectory)FrameworkTests\FrameworkTests.feature">
因此,当将其更改为内容文件夹时,您的。nuspec
文件应为:
<files>
<file src="build\MyProject.targets" target="build\MyProject.targets" />
<file src="content\FrameworkTests\FrameworkTests.feature" target="content\FrameworkTests\FrameworkTests.feature" />
</files>
.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>
第二点需要更新:
CopyToOutputDirectory
文件中.targets
的值应为 PreserveNewest 如果较新则不复制。
您需要了解:
当您使用此方法更改FrameworkTests.feature
的属性时,此文件的属性在解决方案资源管理器中不会更改,但是,MSBuild将在您构建项目时应用此更改。这是因为在编译项目时将解析<Import Project="....\MyProject.targets" Condition="Exists('...')" />
。
因此,您可以在构建项目后检查CopyToOutputDirectory
文件属性的输出(构建项目后,文件FrameworkTests.feature
将被复制到输出文件夹。)
<强> UPDATE2:强>
很多评论都说不能运行PowerShell脚本 构建服务器,因为install命令不运行它们;只要 VisualStudio将
不确定PowerShell脚本无法在构建服务器上运行的所有原因,但绝大多数是因为PowerShell的默认安全级别。
尝试在PowerShell中输入:
set-executionpolicy remotesigned
在Visual Studio 2015中,您需要安装扩展程序PowerShell Tools for Visual Studio 2015和Windows Management Framework 4.0。安装后,install.ps1将正常工作。以下是我的.nuspec
文件和install.ps
1脚本。
.nuspec文件:
<files>
<file src="content\FrameworkTests\FrameworkTests.feature" target="content\FrameworkTests\FrameworkTests.feature" />
<file src="scripts\Install.ps1" target="tools\Install.ps1" />
</files>
注意:请勿忘记删除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"))
然后,在安装nuget包之后,FrameworkTests.feature文件的属性将更改为copy if newer
:
希望这有帮助。