wez*_*ten 5 msbuild visual-studio
有很多文章(比如这个和这个)展示了如何添加要发布的文件,他们都说要在发布配置文件(.pubxml)中添加这样的内容:
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\Extra Files\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
Run Code Online (Sandbox Code Playgroud)
为什么需要新_CustomFiles项目?为什么不简单<FilesForPackagingFromProject Include="..\Extra Files\**\*">?我尝试过,由于某种原因,这会导致项目中的每个文件都在已部署的Extra Files文件夹中结束.有人能解释一下这种行为吗?
既然您要问为什么需要这样做,我将不得不深入研究此代码的含义以解释您所看到的内容。<Message />是我们的朋友!
%我们先来看看在<Message>任务中使用 % 是什么意思:
<ItemGroup>
<_CustomFiles Include="..\Extra Files\**\*" />
</ItemGroup>
<Message Text="File: %(_CustomFiles.Identity)" />
Run Code Online (Sandbox Code Playgroud)
当你运行它时,你会得到以下输出:
File: ..\Extra Files\file1.txt
File: ..\Extra Files\file2.txt
File: ..\Extra Files\file3.txt
...
File: ..\Extra Files\etc.txt
Run Code Online (Sandbox Code Playgroud)
基本上,Message任务为项目组中的每个项目运行一次,因为我们使用了 %.
在我们对其进行任何更改之前,让我们先看一下项目组。当此任务开始时,其中FilesForPackagingFromProject已经包含所有文件,具有各种元数据属性,包括DestinationRelativePath. 让我们通过将这个添加到我们的任务中来看看它:
<Message Text="File: %(FilesForPackagingFromProject.Identity) -> %(FilesForPackagingFromProject.DestinationRelativePath)" />
Run Code Online (Sandbox Code Playgroud)
这输出:
File: ..\obj\TempBuildDir\PrecompiledApp.config -> PrecompiledApp.config
File: ..\obj\TempBuildDir\Web.config -> Web.config
File: ..\obj\TempBuildDir\App_Themes\theme.css -> App_Themes\theme.css
...
Run Code Online (Sandbox Code Playgroud)
重要的是要意识到这个项目组一开始就不是空的。您正在尝试向其中添加项目。
当您在具有 % 的元素中有子元素时,它们会应用于每次迭代一次,所以现在让我们看一下工作代码:
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<Message Text="File: %(FilesForPackagingFromProject.Identity) -> %(FilesForPackagingFromProject.DestinationRelativePath)" />
Run Code Online (Sandbox Code Playgroud)
对于 中的每个项目_CustomFiles,我们将其包含在FilesForPackagingFromProject项目组中,并将DestinationRelativePath元数据属性设置为适当的 RecursiveDir/Filename值 - 基本上是适用于正在查看的当前元素的值。让我们看看这个输出是什么:
File: ..\obj\TempBuildDir\PrecompiledApp.config -> PrecompiledApp.config
File: ..\obj\TempBuildDir\Web.config -> Web.config
File: ..\obj\TempBuildDir\App_Themes\theme.css -> App_Themes\theme.css
...
File: ..\Extra Files\file1.txt -> Extra Files\file1.txt
File: ..\Extra Files\file2.txt -> Extra Files\file2.txt
File: ..\Extra Files\file3.txt -> Extra Files\file3.txt
...
File: ..\Extra Files\etc.txt -> Extra Files\etc.txt
Run Code Online (Sandbox Code Playgroud)
如果你只想包含一个文件,你可以这样做:
<FilesForPackagingFromProject Include="..\Extra Files\file1.txt">
<DestinationRelativePath>Extra Files\file1.txt</DestinationRelativePath>
</FilesForPackagingFromProject>
Run Code Online (Sandbox Code Playgroud)
这不会%在任何地方扩展,因此它完全符合您的期望:它在输出中包含一个文件。
现在让我们尝试包含单个文件,但不对路径进行硬编码,而是使用原始代码中的 % 表达式:
<FilesForPackagingFromProject Include="..\Extra Files\file1.txt">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<Message Text="File: %(FilesForPackagingFromProject.Identity) -> %(FilesForPackagingFromProject.DestinationRelativePath)" />
Run Code Online (Sandbox Code Playgroud)
这里有%所以事情得到扩展,但因为这%在项目组元素中没有 a ,扩展的工作方式不同,事情变得梨形:
File: ..\obj\TempBuildDir\PrecompiledApp.config -> PrecompiledApp.config
File: ..\obj\TempBuildDir\Web.config -> Web.config
File: ..\obj\TempBuildDir\App_Themes\theme.css -> App_Themes\theme.css
...
File: ..\Extra Files\file1.txt -> Extra Files\PrecompiledApp.config
File: ..\Extra Files\file1.txt -> Extra Files\Web.config
File: ..\Extra Files\file1.txt -> Extra Files\theme.css
Run Code Online (Sandbox Code Playgroud)
因此file1.txt,它不是一次添加到项目组,而是遍历整个集合并file1.txt为其中已有的每个文件添加一次。RecursiveDir未在此上下文中设置,而Filename/Extension组中每个文件的原始文件名。
希望您现在可以看到这将为整个部署中的每个文件创建一个文件,但在一个扁平的树中,值得注意的是,内容将是file1.txt原始文件的内容而不是原始文件。
当您包含通配符而不是仅包含一个文件时,与通配符匹配的每个文件都会发生同样的事情。
坚持%(_CustomFiles)修复。希望你现在会明白为什么它是必要的,以及它是如何做的。我确实相信这就是你应该这样做的方式:这是另一个关于它的问题,答案是推荐这种方法。
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |