为什么Visual Studio中的ClickOnce不从依赖程序集部署内容文件?

时间:2009-02-26 11:55:19

标签: .net clickonce

我有一个智能客户端应用程序,通过点击一次部署。问题是我在依赖程序集中有内容文件,而这些内容文件只是没有出现在visual studio中已发布的应用程序文件对话框中。

这意味着每次部署时我都必须将所有内容文件从应用程序构建输出目录复制到已发布的目录中,并重建清单,这是一个真正的痛苦。

为什么Visual Studio中的发布者看不到这些文件?

5 个答案:

答案 0 :(得分:10)

我似乎找到了@John Hunter答案的演变,这个答案要简单得多,将其添加到csproj中。

<ItemGroup>
    <Content Include="Bin\**\*.rpt" />
</ItemGroup>

这将使visual studio自动查看该文件夹中的所有* .rpt文件,作为解决方案的一部分。您可以使用*.*来累积所有内容。如果您有像bin\MyDeployables\**\*.*

这样的容器文件夹,这会更有意义

我们遵循类似的用法,使用Cassette MSBuild在发布时组合和减少我们的JS,并能够通过内置的VS发布工具发布创建的文件。

答案 1 :(得分:3)

我认为this post的答案可以回答你的问题。

<强>摘要
要么...
使用“添加为链接”功能将您的内容文件添加到项目中。
或...
创建一个构建后事件以将内容文件复制到主输出文件夹。

答案 2 :(得分:3)

好吧我仍然不知道为什么Visual Studio无法使用其发布ui显示引用的内容文件,但我找到了一个解决方法来强制发布包含这些文件。

根据this MSDN article的建议,将其放在项目文件中。

<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(而不仅仅是重新加载项目)才能使这些更改生效。

答案 3 :(得分:0)

我认为此解决方案基于:http://blogs.msdn.com/mwade/archive/2008/06/29/how-to-publish-files-which-are-not-in-the-project.aspx

根据我最近对帖子的评论:

  

我们应该在什么时候期待这些   出现在“应用程序文件”中   列表(如果有的话)?

     

或者可以安全地假设他们最终会进入   我们部署的数据文件列表?

     

在我的情况下,我希望使用:

     

     

     

错误

     

     

     

包含所有内容文件   内部的依赖程序集   构建的“Resources”子文件夹   。目录

安德鲁。

答案 4 :(得分:0)

将此内容添加到.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包中发布此功能,以使其更易于安装此脚本。如果有链接,我会发布一个链接。