我有一个通过单击部署的智能客户端应用程序。问题是我在依赖程序集中有内容文件,这些文件只是没有显示在 Visual Studio 的已发布应用程序文件对话框中。
这意味着每次部署时,我都必须将应用程序构建输出目录中的所有内容文件复制到已发布目录中并重建清单,这真的很痛苦。
为什么 Visual Studio 中的发布者看不到这些文件?
我似乎从@John Hunter 找到了一个更简单的答案演变,将其添加到 csproj。
<ItemGroup>
<Content Include="Bin\**\*.rpt" />
</ItemGroup>
这将使 Visual Studio 自动查看该文件夹中的所有 *.rpt 文件作为解决方案的一部分。你可以去*.*
积累一切。如果您有一个容器文件夹,这更有意义bin\MyDeployables\**\*.*
我们遵循类似的用法,使用 Cassette MSBuild 在发布时合并和缩小我们的 JS,并能够通过内置的 VS 发布工具发布创建的文件。
我想我在这篇文章中的回答回答了你的问题。
摘要
要么...
使用“添加为链接”功能将您的内容文件添加到您的项目中。
或者...
创建一个构建后事件以将您的内容文件复制到主输出文件夹。
好的,我仍然不知道为什么 Visual Studio 无法使用其发布 ui 显示引用的内容文件,但我找到了一种解决方法来强制发布包含这些文件。
正如这篇 MSDN 文章所建议的,将其放入项目文件中。
<ItemGroup>
<AdditionalPublishFile Include="$(OutputPath)\**\*.rpt">
<Visible>False</Visible>
</AdditionalPublishFile>
</ItemGroup>
<Target Name="BeforePublish">
<Touch Files="@(IntermediateAssembly)" />
<CreateItem Include="@(AdditionalPublishFile)" AdditionalMetadata="TargetPath=%(RecursiveDir)%(Filename)%(extension);IsDataFile=false">
<Output TaskParameter="Include" ItemName="_DeploymentManifestFiles" />
</CreateItem>
</Target>
请注意,在某些情况下,可能需要重新启动 Visual Studio(而不仅仅是重新加载项目)才能使这些更改生效。
我认为这个解决方案是基于:http: //blogs.msdn.com/mwade/archive/2008/06/29/how-to-publish-files-which-are-not-in-the-project.aspx
根据我最近对该帖子的评论:
我们应该在什么时候期望这些出现在“应用程序文件”列表中(如果有的话)?
或者可以安全地假设它们最终会出现在我们部署的数据文件列表中?
就我而言,我希望使用:
错误的
包含来自构建目录的“资源”子文件夹中的依赖程序集的所有内容文件。
安德鲁。
将此添加到 .csproj / .vbproj 的底部可解决此问题。它获取依赖项目的已经缓存的目标项,并将它们显式添加到应用程序清单中,然后也会在分发清单中发布
<Target Name="MyAddAdditionalPublishItemsFromDependencies" BeforeTargets="GenerateApplicationManifest">
<!-- Get items from child projects first. This just fetches data cached by MSBuild -->
<MSBuild
Projects="@(_MSBuildProjectReferenceExistent)"
Targets="GetCopyToOutputDirectoryItems"
BuildInParallel="$(BuildInParallel)"
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform); %(_MSBuildProjectReferenceExistent.SetTargetFramework)"
Condition="'@(_MSBuildProjectReferenceExistent)' != '' and '$(_GetChildProjectCopyToOutputDirectoryItems)' == 'true' and '%(_MSBuildProjectReferenceExistent.Private)' != 'false' and '$(UseCommonOutputDirectory)' != 'true'"
ContinueOnError="$(ContinueOnError)"
SkipNonexistentTargets="true"
RemoveProperties="%(_MSBuildProjectReferenceExistent.GlobalPropertiesToRemove)">
<Output TaskParameter="TargetOutputs" ItemName="_AllChildProjectItemsWithTargetPath"/>
</MSBuild>
<ItemGroup>
<!-- Filter out the interesting files from MSBuild -->
<_AllImportedCopyItems KeepDuplicates="false" KeepMetadata="CopyToOutputDirectory;TargetPath" Include="@(_AllChildProjectItemsWithTargetPath->'%(FullPath)')" Condition="'%(_AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(_AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'" />
<!-- Get auto copied DLLs with these references -->
<_AllReferenceAutoCopyItems KeepDuplicates="false" KeepMetadata="CopyToOutputDirectory;TargetPath" Include="@(ReferenceCopyLocalPaths)"/>
</ItemGroup>
<ItemGroup>
<!-- Release memory for huge list -->
<_AllChildProjectItemsWithTargetPath Remove="@(_AllChildProjectItemsWithTargetPath)"/>
</ItemGroup>
<ItemGroup>
<!-- Filter non-dll -->
<_AllReferenceAutoCopyItems Remove="%(_AllReferenceAutoCopyItems.Identity)" Condition="'%(_AllReferenceAutoCopyItems.Extension)' != '.dll'" />
<!-- Remove items which we already have in the deployment manifest -->
<_AllReferenceAutoCopyItems Remove="@(_DeploymentManifestFiles);@(_DeploymentManifestDependencies)" />
</ItemGroup>
<!-- Replace items in _AllReferenceAutoCopyItems with the items emitted by the AssignTargetPath task that have the TargetPath metadata -->
<AssignTargetPath Files="@(_AllReferenceAutoCopyItems)" RootFolder="$(MSBuildProjectDirectory)">
<Output TaskParameter="AssignedFiles" ItemName="_Temporary" />
</AssignTargetPath>
<ItemGroup>
<_AllReferenceAutoCopyItems Remove="@(_Temporary)" />
<_AllReferenceAutoCopyItems Include="@(_Temporary)" />
<_Temporary Remove="@(_Temporary)" />
</ItemGroup>
<!-- And now declare these items as files for deployment -->
<ItemGroup>
<_DeploymentManifestFiles Include="@(_AllImportedCopyItems)">
<IncludeHash Condition="'%(Extension)' == '.dll' or '%(Extension)' == '.exe'">True</IncludeHash>
<IsDataFile>false</IsDataFile>
</_DeploymentManifestFiles>
<_DeploymentManifestFiles Include="@(_AllReferenceAutoCopyItems)">
<IncludeHash Condition="'%(Extension)' == '.dll' or '%(Extension)' == '.exe'">True</IncludeHash>
<IsDataFile>false</IsDataFile>
</_DeploymentManifestFiles>
</ItemGroup>
<!-- Remove items which we will never again use - they just sit around taking up memory otherwise -->
<ItemGroup>
<_AllImportedCopyItems Remove="@(_AllImportedCopyItems)" />
<_AllReferenceAutoCopyItems Remove="@(_AllReferenceAutoCopyItems)" />
</ItemGroup>
</Target>
我正在考虑在 .NuGet 包中发布此功能,以便更轻松地安装此脚本。当我有一个链接时,我会发布一个链接。