根据当前操作系统 (Windows/Linux),将本机库复制到 Visual Studio 或 MonoDevelop 中每个构建的输出目录

Copy Native Libraries to Output directory on every Build in Visual Studio or MonoDevelop based on current Operating System (Windows/Linux)

我正在开发一个目前正在 VS 2017 中开发的 C# WinForms 项目,不过,它将部署在 Linux 机器上 Ubuntu 16.04 LTS 使用 Mono 框架(MonoRuntime).

我在我的项目中引用了 EmguCV v3.2SQLite。这两个都是 .NET 托管程序集,依赖于它们自己的本机库(EmguCV 使用 cvextern.dllSQLite 使用 SQLite.Interop.dll)。

由于这个应用程序将部署在 Linux 机器上,我已经为它们编译并构建了 .so 库文件(libcvextern.solibSQLite.Interop.so准确地说)成功。

为了让我的应用程序在 Windows 上运行,2 个 .so 文件是多余的,而当我的应用程序在 Linux 下的 Mono 下运行时它们是必需的(并且它们必须是始终在执行目录中!)。

我的问题是,我想让 Visual Studio 2017 或 MonoDevelop 明白如果我在 Windows(或者 Debug/Release)上构建,我需要 .dll要复制到输出目录 (OR) 的文件类似于 .so 文件,如果在 Linux 上。你如何处理这个问题?

那么,我如何正确设置一个 Post-Build 事件,VS 2017 和 MonoDevelop 都尊重它们在构建时识别底层当前操作系统并将相应的 lib 文件复制到输出目录?

对于任何英语语法问题,我深表歉意,我不是母语人士。

不胜感激!

好的,我已经通过 3 个步骤解决了这个问题(搜索了几个小时之后)。

如上所述,如果项目是在 Windows 上构建的(Debug/Release),我的要求是将 .dll 文件复制到输出目录,并复制 .so 对应的文件如果项目是在 Linux 上使用 MonoDevelop 构建的 (Debug/Release),则为 libs。

  1. 我将库复制到项目文件夹中的一个目录(安全的地方),然后在 VS 2017 中使用 Add Existing Item --> 选择所需的 lib 文件 --> 使用 Add as Link 而不是Open (找到这个 from here)。
  2. 我需要将它们复制到输出目录,而没有从我将它们添加到项目时继承的文件夹结构,所以我遵循了 accepted answer to this question 并且能够指示它在每个构建中复制到输出目录.
  3. 现在对于最终要求,即根据底层操作系统复制特定文件,我在 .csproj 文件的 ItemPropertyGroup 中使用了 Condition 属性。这是我所做的:

如果基础 OS 是 Windows,我有 1 个 .dll 要包含,如果是 linux,我有 2 个 .so 文件,这是我对它们的配置在 .csproj 文件中修改。

<ContentWithTargetPath Include="references\libDependencies\linux64\libcvextern.so" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  <TargetPath>libcvextern.so</TargetPath>
</ContentWithTargetPath>


<ContentWithTargetPath Include="references\libDependencies\linux64\libSQLite.Interop.so" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  <TargetPath>libSQLite.Interop.so</TargetPath>
</ContentWithTargetPath>


<ContentWithTargetPath Include="references\libDependencies\win64\cvextern.dll" Condition=" '$(OS)' == 'Windows_NT' ">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  <TargetPath>cvextern.dll</TargetPath>
</ContentWithTargetPath>

不出所料,从现在开始,每次构建(Debug/Release)时,相应的库都会被复制到输出目录。就这些了,希望对大家有帮助。