Why doesn't ClickOnce in Visual Studio deploy content files from dependent assemblies?

后端 未结 5 1649
一个人的身影
一个人的身影 2020-11-30 08:58

I have a smart client application that is deployed via click once. The problem is that i have content files in dependent assemblies that just don\'t show up in the publishe

相关标签:
5条回答
  • 2020-11-30 09:22

    I think my answer from this post answers your question.

    Summary
    Either...
    Add your content files to your project using the "Add as link" feature.
    Or...
    Create a post-build event to copy your content files to the main output folder.

    0 讨论(0)
  • 2020-11-30 09:28

    I assume this solution was based on: http://blogs.msdn.com/mwade/archive/2008/06/29/how-to-publish-files-which-are-not-in-the-project.aspx

    As per my recent comment on the post:

    At what point should we expect these to appear in the "Application Files" listings (if at all)?

    Or is safe to assume they'll end up in our deployed data files listing?

    In my case I'm hoping to use:

    False

    To include all content files from dependent assemblies that are within the "Resources" subfolder of the build directory.

    Andrew.

    0 讨论(0)
  • 2020-11-30 09:32

    Ok I still don't know why Visual studio cannot display referenced content files with its publish ui but I found a work around to force the publish to include these files.

    As suggested by this MSDN article, put this in the project file.

    <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>
    

    Note that in some circumstances restarting Visual Studio (not just reloading the project) may be required for these changes to take effect.

    0 讨论(0)
  • 2020-11-30 09:34

    I seemed to have found an evolution of the answer from @John Hunter that is much simpler, add this to the csproj.

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

    This will then make visual studio automatically view all *.rpt files in that folder as part of the solution. You could go with *.* to accumulate everything. This makes more sense if you have a container folder like bin\MyDeployables\**\*.*

    We followed a similar usage for using Cassette MSBuild to combine and minifiy our JS at publish time, and be able to publish the created files through the built in VS publish tooling.

    0 讨论(0)
  • 2020-11-30 09:45

    Adding this to the bottom of your .csproj / .vbproj fixes this issue. It takes the already cached target items of depending projects and explicitly adds them to the application manifest, which is then also published in the distribution manifest

    <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>
    

    I'm thinking about publishing this feature in a .NuGet package, to make it easier to install this script. I will post a link when I have one.

    0 讨论(0)
提交回复
热议问题