Visual Studio自动复制原生dll到引用项目的bin文件夹

Automaticaly copy native dll to the bin folder of referencing project in Visual Studio

我有一些本机dll,必须根据平台条件将其复制到bin 文件夹中。我希望将它们复制到引用该项目的项目的 bin 文件夹中。

如果我将构建操作设置为 Content,它们将被复制到 bin 文件夹,但文件夹结构保持不变,因此它们不会在 bin 文件夹中,而是在子文件夹中文件夹。所以当运行程序时,它将无法解析dll,因为它们在子文件夹中。

例如,如果我在项目文件中有这段代码

<Choose>
    <When Condition=" '$(Platform)'=='x86' ">
      <ItemGroup>
        <Content Include="nativedll\somelib\x86\somelib.dll">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
      </ItemGroup>
    </When>
    <When Condition=" '$(Platform)'=='x64' ">
      <ItemGroup>
        <Content Include="nativedll\somelib\x64\somelib.dll">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
      </ItemGroup>
    </When>
  </Choose>

如果是 x86,dll 将在文件夹 bin\nativedll\somelib\x86\somelib.dll 中。

所以我尝试使用 Post 构建脚本

<PostBuildEvent>

            IF "$(Platform)" == "x86" (
            xcopy /s /y "$(ProjectDir)\nativedll\somelib\x86" "$(TargetDir)"
            )
            IF "$(Platform)" == "x64" (
            xcopy /s /y "$(ProjectDir)\nativedll\somelib\x64" "$(TargetDir)"
            )
</PostBuildEvent>

但是dll被复制到项目的bin文件夹中,而不是引用它的项目的bin文件夹中。

所以我现在的解决方案是在所有使用此脚本的项目中添加一个 post 构建脚本。

在 Visual Studio 中有更好的方法吗?

尝试对每个必须复制的文件使用此方法(csproj 文件 - 创建一个项目组):

<ItemGroup>
   <ContentWithTargetPath Include="mySourcePath\myFile.dll">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <TargetPath>myFile.dll</TargetPath>
 </ContentWithTargetPath >
</ItemGroup>

引用项目还应包含复制的文件。


以下内容也可能有所帮助:

在 Visual Studio 项目中本地复制本机依赖项

将 NuGet 包中的本机文件添加到项目输出目录 @kjbartel

我给出了我在得到@dajuric anwser 之前使用的解决方案。 我更喜欢 dajuric 解决方案,因为它不涉及在其他文件夹中查找代码。

我在 csproj 中使用了条件内容。

<When Condition=" '$(Platform)'=='x86' ">
      <ItemGroup>
        <Content Include="nativedll\somelib\x86\somelib.dll">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
      </ItemGroup>
    </When>
//same for x64
    ...

然后在使用本机 dll 初始化库之前,我使用 kernel32 SetDllDirectory.

将该文件夹添加到 dll 查找文件夹列表中
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetDllDirectory(string lpPathName);

 SetDllDirectory(@".\nativedll\somelib\x"+ (Environment.Is64BitProcess ? "64" : "32"));