自动将本机dll复制到Visual Studio

时间:2017-09-22 09:17:51

标签: c# visual-studio dll unmanaged

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

如果我将构建操作设置为内容,它们将被复制到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文件夹中。

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

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

2 个答案:

答案 0 :(得分:4)

尝试将此文件用于每个必须复制的文件(csproj文件 - 制作项目组):

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

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

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

Copy native dependencies locally in a Visual Studio project

Add native files from NuGet package to project output directory @kjbartel

答案 1 :(得分:0)

我给出了@djuric 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"));