具有 false 值的 ReferenceOutputAssembly 标签的项目引用不会复制其 SatelliteDll

Project Reference with ReferenceOutputAssembly tag with false value does not copy its SatelliteDlls

根据这个link https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project-reference-without-referencing-the-actual-binary/

我使用 ReferenceOutputAssembly=false 在项目 B 中引用了项目 A 的程序集,如下所示:

    <ProjectReference Include="..\ProjectA\ProjectA.csproj">
      <Project>{b402782f-de0a-41fa-b364-60612a786fb2}</Project>
      <Name>ProjectA</Name>
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
      <OutputItemType>Content</OutputItemType>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </ProjectReference>

这将指示项目之间对 MSBuild 的依赖性,但不会在编译 ProjectB 时将 ProjectA 的输出程序集作为引用传递给编译器。 MSBuild 只是将程序集 A dll 复制到程序集 B 的输出目录中,而不是 Satellite Dll。 我需要输出目录中的 ProjectA.dll 和 ProjectA.resources.dll 但只复制了 projectA.dll,项目 A 的 Satellite Dll 没有被复制..

MSBuild just copies the assembly A dll into the output directory for assembly B ,not the Satellite Dll. I need both ProjectA.dll and ProjectA.resources.dll in the output directory but just projectA.dll is copied , Satellite Dll of Project A is not copied..

这个问题也出现在我这边,我认为当你使用上面的函数(link中的方法)时,它会在不引用项目 A 的情况下复制依赖关系,但也会忽略 DLL 或 resources.dlls被项目A引用。这种方式关注项目依赖,忽略项目使用的其他第三方DLL。

此行为是您使用的场景的特征。

但是,如果你仍然想使用这个功能来引用项目A,你可以尝试在构建时使用构建事件或复制任务将ProjectA.resources.dll复制到项目B的输出路径中:

1) 右键单击​​项目 B-->Properties-->Build Events-->Post-Build Event Command line 然后输入:

xcopy /y "xxxxxxxxxxx\de\ProjectA.resources.dll" "$(ProjectDir)$(OutputPath)de"

xcopy /y path1 path2:path1表示原文件路径,path2表示目标地址

更新 1

generally your solution works but it doesnt work for me because I want to publish with clickonce and Postbuildevent is not called during the publish .. I added a before publish tag in csproj of the project B to run the postbuildevent but it doesnt work

首先,你不必运行在错误的目标发布后自定义目标,而是应该使用PublishBuild目标。然后在执行clickonce操作的过程中使用复制任务将文件复制到Puplish文件夹中。

毕竟,你可以试试我在 ProjectB.csproj 文件中测试成功的示例。

<Target Name="CopyToPublish" AfterTargets="PublishBuild">
    <ItemGroup>
      <ResourceFiles Include="xxxxxxx\ProjectA.resources.dll" />   // the path of the ProjectA.resources.dll
    </ItemGroup>
    <Copy SourceFiles="@(ResourceFiles)" DestinationFiles="@(ResourceFiles->'$(PublishUrl)\de\%(RecursiveDir)%(Filename)%(Extension)')" />
  </Target>

更新 2

经过我的研究,我发现当 VS 将文件放入 Clickonce Manifest 时,它 运行 是目标(GenerateApplicationManifestGenerateDeploymentManifestGenerateManifests 等等) sequentially.These 是作为文件具体执行到清单中的目标。所以当你使用你的 BeforePublish 目标将额外的文件作为一个项目时,你应该在目标之前 运行 。所以请试试这个:

<Target Name="BeforePublish" BeforeTargets="GenerateApplicationManifest">
    <ItemGroup>
      <AdditionalPublishFile Include="xxxxxxx\de\ProjectA.resources.dll">
        <Visible>False</Visible>
      </AdditionalPublishFile>
    </ItemGroup>
    <Touch Files="@(IntermediateAssembly)" />
    <CreateItem Include="@(AdditionalPublishFile)" AdditionalMetadata="TargetPath=de\%(FileName)%(Extension);IsDataFile=false">
      <Output TaskParameter="Include" ItemName="_DeploymentManifestFiles" />
    </CreateItem>
  </Target>

当您发布项目时,ProjectA.resources.dll 将成功显示在ProjectB.manifest 文件中。但是多余的文件在属性UIPublish-->Application Files中不会显示,我觉得这是UI显示的问题,不影响这个文件的输出。

希望对您有所帮助。