Visual Studio 不复制链接文件的目录

Visual Studio not Copying Directory of Linked Files

暂存非托管库或资源时的常见做法是将这些资源作为链接添加到项目并将它们设置为复制到输出目录。

从 Visual Studio 2013 年开始,这得到了很好的处理,即使它们被引用库 Foo 然后被应用程序 Bar 使用,它们最终也会在 Bar的输出目录。

虽然文件目录似乎并非如此。

在这种情况下,我的应用程序似乎仅在 rebuild 上将此文件目录复制到输出目录。然后我不可避免地会执行几个 build 操作,我会注意到 Libs 目录再次为空。然后做一个 Rebuild 然后 cef.pak 回来了。

我的解决方案是使用 Build StepLibs 目录手动复制到输出目录。虽然我找不到合适的宏来一般地表达即使这个构建步骤是 Foo 的一部分,但我希望将文件复制到 Bar 的(例如 StartUp Project 在 VS 术语中)输出目录。

更新

感谢大家的精彩回答和测试。我应该澄清一下,当中间有一个额外的库级别时,我仍然会看到这个问题。也就是说,应用程序 Bar 引用库 Foo,而库 Foo 引用库 Other,即带有这些链接文件的库。在那种情况下,当 Other 的链接文件设置为复制到输出目录时,它们似乎只在重建时才复制。我对此的解决方案不太理想,即 Foo 直接引用 Other

尝试用 VS2013 做同样的事情。它工作得很好,每次我在 Bar 的文件 运行 Foo(启动项目)中更改某些内容时,最新的文件都会复制到那里。我只是在写我遵循的步骤,可能是我遗漏了一些要复制的东西,或者你错过了一个步骤。请看:

  1. 创建两个项目 Foo 和 Bar
  2. 在 Bar 中创建了一个目录 Libs
  3. 在 Libs
  4. 中添加了一个文本文件 "TextFile1.txt"
  5. 右键单击 -> 文件属性 -> 复制到输出目录 = 始终复制
  6. 添加了 Foo 项目中的 Bar 引用
  7. 开始从 Foo 的 Main 方法读取 TextFile 的文本。从 Bin\Debug\Libs 目录读取文件。
  8. 每次我按 F5 时,我都会看到最新的文件被复制到那里。

除非您 rebuild/clean 解决方案,否则 VS 会从输出文件夹中删除文件。 所以我相信你忘了说你的程序(或第三方)这样做了。

首先:this 是 similar/exact 错误的示例。
下载解决方案并执行以下步骤:

  1. 重建解决方案
  2. 打开 Bar 的输出文件夹
  3. 文件 cef.pak 将存在于 Libs
  4. 按 F5 -> 执行 Bar -> 一切正常
  5. 使用 F5 再次执行 -> 您将收到一个文件未找到异常
  6. 如果您重复步骤 1-5,您将收到相同的行为

    • 只有在 Bar 中没有任何变化并且某些东西(exe / 其他 process/etc)删除了文件时才会存在此问题。

其次:我已经遇到过这个问题。 当我的一位团队成员报告此问题时,他收到的答案是一种 "it's not a bug it's a feature"...

据我所知,没有 "magic button" 可以解决这个问题。

但有几种解决方法:

  1. (如您所做)添加 pre/post 构建事件。我建议您在新构建配置中执行此操作。

  2. 将 Foo 的构建输出文件夹更改为 Bar 输出文件夹。

  3. 在您的代码中添加路径替换 if debug:

    #if DEBUG
                cefFilePath = <build output of foo>
    #endif
    
  4. 将文件作为嵌入资源然后解压。

  5. 创建一个 extension\external 程序来处理这个问题。每个项目文件都保留有关这些文件的信息:

  <ItemGroup>
    <None Include="Libs\cef.pak">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

application/plugin 会为您完成这项工作。

我可以提供更多 solutions/workarounds,但我相信您做对了 -> 构建事件。

编辑:

我在 link 中更新了示例。现在解决方案包含 3 个解决方法示例。

编辑"Foo.csproj"(确保项目在 VS 中关闭)并在底部添加这个,以代替每个新项目文件中已经存在的注释掉的示例(使用您自己的路径) :

<Target Name="AfterBuild">
    <Copy SourceFiles="Libs\cef.pak;Libs\file2.ext" DestinationFolder="..\..\Bar Solution\Bar Project\output" SkipUnchangedFiles="True" OverwriteReadOnlyFiles="True" />
</Target>

同时编辑 "Bar.csproj",以防更改这些文件不会触发 Foo 构建:

<Target Name="BeforeBuild">
    <Copy SourceFiles="..\..\Foo Solution\Foo Project\Libs\cef.pak;..\..\Foo Solution\Foo Project\Libs\file2.ext" DestinationFolder="output" SkipUnchangedFiles="True" OverwriteReadOnlyFiles="True" />
</Target>