从Nuget包中提取的自动本机和托管DLL

Jér*_*VEL 23 c# nuget nuget-package .net-core asp.net-core

这让我疯狂了几个月,我仍然无法实现它.我的托管库是从Nuget包中提取的,但不是本地的.

我们有一堆由其他公司提供的托管和本地库.我们有它们x86x64它们的版本.为了在ASP.NET Core项目中使用它们,我必须创建一个Nuget包.

我的架构是:

  • 我更改为仅针对完整.NET Framework的ASP.NET Core类库.这个项目引用了我的Nuget包
  • 一个ASP.NET Core网站,也是针对完整的.NET Framework并引用类库

当然,最后,我需要将我的本机库提取到网站的正确运行时文件夹(例如:) \bin\Debug\net461\win7-x64.

目前我的解决方案是:

  • 将本机库放在build文件夹中
  • 创建一个targets将它们复制到的文件$(OutputPath)(甚至不是运行时文件夹)
  • 添加一些MsBuild命令到xproj我的网站,以获取我的$(USERPROFILE)\.nuget\packages\文件夹中的目标文件并执行它
  • 手动复制现在在bin文件夹中提取的本机DLL 到runtime一个

我试图使用一些配置直接将它们复制到运行时文件夹中project.json(我真的不记得我为这部分尝试过的所有事情),但这总是失败.即使我SkipUnchangedFiles="true"在我的目标文件中指定,这只是被忽略,我的DLL在每次构建期间被复制到我的bin文件夹.

这是一个重要的过程,只是为了实现DLL提取,现在我真的想摆脱所有MsBuild并得到一个更简单的解决方案.

我知道Nuget的新版本,它现在能够在没有添加自定义MsBuild命令的任何帮助的情况下原生提取它们.至于写在这里,C#项目甚至不需要一个targets文件

接下来,可能使用NuGet包的C++和JavaScript项目需要.targets文件来标识必要的程序集和winmd文件.(C#和Visual Basic项目会自动执行此操作.)

我在我的浏览器中打开了一个标签,持续了几个月(原始链接),并意识到此资源最近已从Nuget网站上删除.它解释了如何使用该runtimes文件夹自动提取本机DLL.然而,我从来没有能够得到一个成功的结果,因为它被解释.现在,这个页面已被删除,取而代之的这一个有这么一些解释,而不是谈论这个runtimes文件夹的.

我的猜测是我应该使用runtimes本机DLL的文件夹和lib托管的那个,但我不是100%肯定.(我也应该使用该build文件夹吗?)

我已经尝试了几件事(我记不起尝试次数,正如我所说的几个月的头痛......)就像这样的架构(我不明白这有什么意义,build/native还有本机文件夹runtimes) 在此输入图像描述

我还尝试使用此处描述的.NET框架版本结构用于托管库.

似乎也是解决方案的一部分

创建程序集引用时,编译器会忽略该体系结构.这是一个加载时间概念.如果存在,加载程序将更喜欢体系结构特定的引用.

可用于生成AnyCPU程序集的一个技巧是使用corflags从x86程序集中删除体系结构.EG:corflags/32BITREQ- MySDK.dll.Corflags是.NET SDK的一部分,可以在VS的开发人员命令提示符中找到.

这就是我所做的,将x86和x64 DLL转换为AnyCPU(不知道它是否为x64 DLL做了什么,但我没有得到错误)然后在我的Nuget包中尝试了几种不同的架构但仍然无法正常工作.

在project.json中没有任何条目的默认运行时是win7-x64,所以我决定明确指定它以防万一

"runtimes": {
    "win7-x64": {}
},
Run Code Online (Sandbox Code Playgroud)

所以这是我用于Nuget包中所有尝试的运行时标识符.但是我并不关心Windows版本.我实际上更喜欢使用win-x86或win-x64,但根据此页面,它似乎是无效值

Windows RID

Windows 7/Windows Server 2008 R2

  • WIN7-64
  • WIN7-86

Windows 8/Windows Server 2012

  • win8的-64
  • win8的-86
  • win8的臂

Windows 8.1/Windows Server 2012 R2

  • win81-64
  • win81-86
  • win81臂

Windows 10/Windows Server 2016

  • win10-64
  • win10-86
  • win10臂
  • win10-arm64

然而,这个Github源代码描述了更多的RID,所以哪个来源是正确的?

正如你所看到的,这里有很多谜团,主要是因为缺乏文档甚至是不同文档之间的矛盾.

如果至少我可以有一个工作示例,那么我可以执行我的测试来回答其他问题,例如尝试通用win-x64RID,或者看看我是否可以包含一次我的托管库,无论.NET Framework版本如何.

请注意我的特殊上下文:我有一个针对完整.NET Framework的ASP.NET Core项目

感谢您的回答,我迫切希望让这个简单的事情发挥作用.

Jér*_*VEL 31

我将尝试尽可能详细地解释我所经历的所有痛苦和解决方案.在我的示例中,我使用简单的文本文件AAA86.txt,AAA64.txtAAAany.txt不是本机DLL来简单地演示提取过程.

首先你需要知道的是: 如果你试图将nativeNuGet的架构与lib包含一些托管库的文件夹混合在一起,它将无法工作

在此输入图像描述

在这种情况下,您的托管DLL将被复制到项目的输出目录,但不是您的原生目录.

感谢Jon Skeet向我指出了良好的方向,建议我看一下Grpc.Core软件包.诀窍是创建一个targets将处理DLL提取的文件.

在此输入图像描述

您的目标文件应包含这样的内容

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <ItemGroup Condition=" '$(Platform)' == 'x64' ">
        <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x64\native\AAA64.txt">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Link>AAA64.txt</Link>
        </Content>
    </ItemGroup>

    <ItemGroup Condition=" '$(Platform)' == 'x86' OR '$(Platform)' == 'AnyCPU' ">
        <Content Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-x86\native\AAA86.txt">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Link>AAA86.txt</Link>
        </Content>
    </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

现在您需要知道的其他一些事情:

1) Visual Studio 根本不关心您选择的设置,它总是使用虚拟RID.(在我的情况下,win7-x64即使我在Windows 10 上,我总是最终得到一个文件夹......)

在此输入图像描述

2)你的平台设置project.json也完全没用

{
    "buildOptions": {
        "platform": "x64"
    }
}
Run Code Online (Sandbox Code Playgroud)

3)运行时设置中,如果仅设置win和/或win-x64

"runtimes": {
    "win": {},
    "win-x64": {}
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio将改为使用win7-x64.但是如果你win10-x64在Windows 10机器上添加,那么将使用它

4)如果使用这样的通用RID编译应用程序

dotnet build -c debug -r win
Run Code Online (Sandbox Code Playgroud)

然后你的targets文件将收到你的机器的架构(在我的情况下是x64)而不是AnyCPU我期望的

5)如果您只有没有任何托管的本机库,那么如果您遵循该体系结构,则提取将在没有目标文件的情况下工作runtimes/RID/native

6)在我的包中只有本机库,选择的RID将始终win-x64使用Visual Studio构建,因为我告诉你win7-x64,无论我选择的配置如何,总是创建的运行时文件夹.如果我的包中只有一个winRID,那么它将被成功挑选出来.

  • 如果我能+10,我会的,很好的答案。 (2认同)