在Visual Studio项目中本地复制本机依赖项 [英] Copy native dependencies locally in a Visual Studio project

查看:102
本文介绍了在Visual Studio项目中本地复制本机依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个混合模式的C ++项目,该项目生成一个托管的dll程序集,该程序集导出了一些CLR类(称为Managed.dll)。该项目使用的是本机dll(称为Native.dll)。

I have a mixed mode C++ project producing a managed dll assembly exporting some CLR classes (call it Managed.dll). This project is using a native dll, (call it Native.dll).

当我从另一个生成Client.exe的项目中引用Managed.dll时,一切正常,除了我需要手动将Native.dll复制到与Client.exe相同的文件夹中。

When I reference the Managed.dll from another project producing Client.exe, everything works as expected, except than I need to manually copy the Native.dll in the same folder as Client.exe.

如果有办法说服VS在本地复制(在垃圾箱中)

If there a way to convince VS to copy locally (in the bin folder of Client.exe) not only Managed.dll but Native.dll as well?

我试图在清单中包括Native.dll作为依赖程序集,但这没有帮助。

I have tried to include Native.dll as a dependency assembly in the manifest but this didn't help.

编辑

Managed.dll将成为可重新分发的程序集。它将安装在 C:\Program Files .....的文件夹中。当使用Visual Studio的开发人员添加对Managed.dll的引用时,Native.dll也应复制到其项目的\bin文件夹中。

Managed.dll is going to be a redistributable assembly. It will be installed in a folder in "C:\Program Files.....". When a developer using Visual Studio adds a reference to Managed.dll, Native.dll should be also copied in the \bin folder of his project.

推荐答案

有几种方法可以告诉VS将dll复制到目标文件夹:

There are several ways to tell the VS to copy dlls to the destination folder:

1。将dll添加为项目的资源。并告诉VS如果dll是较新的副本

1.Add the dll as a resource of the project. And tell the VS to copy it if the dll is newer

2。添加一个引用该dll项目的新项目,并将OutDir设置为所需的文件夹。该项目除了复制dll外什么都不做。

2.Add a new project that reference to the dll project, and set the OutDir to the folder you want. This project does nothing but copy the dll.

3。在vcxproj文件中使用PostBuildEvent

3.Use a PostBuildEvent in vcxproj file

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
  <ClCompile>
  </ClCompile>
  <Link>
  </Link>
  <PostBuildEvent>
    <Command>
      echo off
      mkdir "$(ProjectDir)..\..\bin\$(Configuration)\"
      copy "$(OutDir)xxx.dll" "$(ProjectDir)..\..\lib\$(Configuration)\"
      echo on
    </Command>
  </PostBuildEvent>
</ItemDefinitionGroup>

4。在vcxproj文件中使用PreBuildEvent

4.Use a PreBuildEvent in vcxproj file

5。在vcxproj文件中使用CustomBuild

5.Use CustomBuild in vcxproj file

<ItemGroup>
<CustomBuild Include="..\..\xxx.dll">
  <FileType>Document</FileType>
  <Command>
   call mkdir &quot;$(OutDir)&quot; 2&gt;nul &amp; 
   copy /Y &quot;..\..\xxx.dll&quot; &quot;$(OutDir)xxx.dll&quot;
  </Command>
  <Message>Copying xxx.dll to $(OutDir)\xxx.dll</Message>
  <Outputs>$(OutDir)\xxx.dll</Outputs>
</CustomBuild>
</ItemGroup>

6。使用makefile并将dll复制到makefile中。并使用nmake来构建

6.Use a makefile and copy dll in makefile. and use nmake to build

7。编写一个执行复制作业的bat文件,然后像3-6一样调用bat文件

7.Write a bat file that do the copy job, and invoke the bat file as in 3-6

8。使用python这样的脚本,也可以从Internet下载dll。然后像3-6一样调用py文件。

8.Use script such as python, which can also download the dll from internet. And invoke the py file as in 3-6.

9。其他构建工具也可以提供帮助,例如gradle

9.Other build tools can help too, such as gradle

10。制作一个NuGet插件

10.Make it a NuGet plugin

11。有时候我只是写了一个蝙蝠,然后手动执行该蝙蝠。

11.Sometimes I just write a bat, and execute the bat manually.

更新01(自解压dll示例):

1。将本机dll添加为托管dll资源

1.Add you native dll as resource of managed dll

2。添加此init()方法

2.Add this init() method

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace DllSelfExtract
{
    public class SelfExtract
    {
        public static void Init()
        {
            String managedDllPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
            String nativeDllPath = managedDllPath.Replace("file:///", "").Replace("DllSelfExtract.DLL", "TestDll.dll");
            if(!File.Exists(nativeDllPath))
            {
                Stream dllIn = Assembly.GetExecutingAssembly().GetManifestResourceStream("DllSelfExtract.TestDll.dll");
                if (dllIn == null) return;

                using (Stream outFile = File.Create(nativeDllPath))
                {
                    const int sz = 4096;
                    byte[] buf = new byte[sz];
                    while (true)
                    {
                        int nRead = dllIn.Read(buf, 0, sz);
                        if (nRead < 1)
                            break;
                        outFile.Write(buf, 0, nRead);
                    }
                }
            }

            //LoadLibrary Here
        }
    }
}

3。在使用托管dll的项目中,首先调用init()方法

3.In project that use your managed dll, invoke init() method first

SelfExtract.Init();

更新02(以NuGet为例):

1。创建一个新的NuGet项目

1.Create a new NuGet project

2。将托管程序集放在/ lib目录中

2.Place the managed assemblies in the /lib directory

3。将非托管共享库和相关文件放在/ build子目录中,并将所有非托管* .dll重命名为* .dl _

3.Place the non-managed shared libraries and related files in the /build subdirectory and rename all non-managed *.dll to *.dl_

4。在/ build子目录中添加一个自定义.targets文件,其内容类似于以下内容:

4.Add a custom .targets file in the /build subdirectory with something like the following contents :

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <AvailableItemName Include="NativeBinary" />
  </ItemGroup>
  <ItemGroup>
    <NativeBinary Include="$(MSBuildThisFileDirectory)*">
      <TargetPath></TargetPath>
    </NativeBinary>
  </ItemGroup>
  <PropertyGroup>
    <PrepareForRunDependsOn>
      $(PrepareForRunDependsOn);
      CopyNativeBinaries
    </PrepareForRunDependsOn>
  </PropertyGroup>
  <Target Name="CopyNativeBinaries" DependsOnTargets="CopyFilesToOutputDirectory">
    <Copy SourceFiles="@(NativeBinary)"
          DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).dll')"
          Condition="'%(Extension)'=='.dl_'">
      <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
    </Copy>
    <Copy SourceFiles="@(NativeBinary)"
          DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).%(Extension)')"
          Condition="'%(Extension)'!='.dl_'">
      <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
    </Copy>
  </Target>
</Project>

5。在Package.nuspec中为build文件夹添加构建规则

5.Add build rule for build folder in Package.nuspec

<files>
  <file src="lib\" target="lib" />
  <file src="tools\" target="tools" />
  <file src="content\" target="content" />
  <file src="build\" target="build" />
</files>

6。构建程序包

7在其他C#项目中,只需添加此NuGet包即可。

7.In your other C# project just add this NuGet package.

这篇关于在Visual Studio项目中本地复制本机依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆