Automatic native and managed DLLs extracting from Nuget Package

前端 未结 2 539
长发绾君心
长发绾君心 2020-11-28 06:59

This is driving me crazy for several months now and I\'m still not able to achieve it. My managed libraries are extracted from the Nuget package but not the natives ones.

相关标签:
2条回答
  • 2020-11-28 07:28

    The problem of native DLLs not being copied to the output directory is gone nowadays when you use dotnet restore instead of nuget.exe restore.

    The issue was solved in my case when using specifically dotnet restore --runtime win-x64 <path_to_the_solution.sln>.

    0 讨论(0)
  • 2020-11-28 07:29

    I will try to explain all the pain and solutions I've been through as detailed as possible. In my example I use simple text files AAA86.txt, AAA64.txt and AAAany.txt instead of native DLLs to simply demonstrate the extraction process.

    First thing you need to know: If you try to mix the native NuGet's architecture with a lib folder containing some managed libraries, IT WILL NOT WORK

    In that case your managed DLLs will be copied to your project's output directory but NOT your native ones.

    Thanks to Jon Skeet who pointed me in the good direction, advising me to take a look at the Grpc.Core package. The trick is to create a targets file that will handle the DLL extraction.

    Your targets file should contain something like this

    <?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>
    

    Also make sure your .targets file is named the same as your AssemblyName. So if the name of your assembly is DemoPackage, your targets file should be named DemoPackage.targets. Otherwise, the .targets file might not be applied when referencing the package in another project. enter image description here

    Now few other things you need to know:

    1) Visual Studio doesn't care at all about the settings you choose, it will always use a dummy RID. (In my case I always end up with a win7-x64 folder even though I'm on Windows 10...)

    2) The platform setting in your project.json is also totally useless

    {
        "buildOptions": {
            "platform": "x64"
        }
    }
    

    3) In the runtimes settings if you set only win and/or win-x64

    "runtimes": {
        "win": {},
        "win-x64": {}
    }
    

    Visual Studio will instead use win7-x64. But if you add win10-x64 while you are on a Windows 10 machine then this will be used

    4) If you compile your application with a generic RID like this

    dotnet build -c debug -r win
    

    Then your targets file will receive the architecture of your machine (x64 in my case) instead of AnyCPU as I was expecting

    5) With only native libraries without any managed ones, the extraction will work without a target file if you follow the architecture runtimes/RID/native

    6) With only native libraries in my package, the chosen RID will always be win-x64 building with Visual Studio as I told you the runtime folder always created is win7-x64, no matter the configuration I select. If I only had one single win RID in my package then it would successfully be picked.

    0 讨论(0)
提交回复
热议问题