Automatic native and managed DLLs extracting from Nuget Package
<p>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.</p>
<p>We have a bunch of managed and native libraries provided by another company.
We have both <code>x86</code> and <code>x64</code> version of them. In order to use them in an ASP.NET Core project I have to create an Nuget Package.</p>
<p>My architecture is:</p>
<ul>
<li>an ASP.NET Core class library that I changed to target full .NET Framework only. This project references my Nuget Package</li>
<li>an ASP.NET Core website also targeting full .NET Framework and referencing the class library</li>
</ul>
<p>Of course, at the end, I need my native libraries being extracted to the proper runtime folder of the Website (eg: <code>\bin\Debug\net461\win7-x64</code>).</p>
<p>For the moment my solution was:</p>
<ul>
<li>to put the native libs inside the <code>build</code> folder</li>
<li>create a <code>targets</code> file that copies them to the <code>$(OutputPath)</code> (which is even not the runtime folder)</li>
<li>add some MsBuild commands to the <code>xproj</code> of my website to get the targets file in my <code>$(USERPROFILE)\.nuget\packages\</code> folder and execute it</li>
<li>copy <strong>by hand</strong> the native DLLs now extracted in <code>bin</code> folder to the <code>runtime</code> one</li>
</ul>
<p>I've tried to copy them directly to the runtime folder using some configuration in <code>project.json</code> (I honestly don't remember all the things I've tried for this part) but this was always failing. Also even though I specified <code>SkipUnchangedFiles=&quot;true&quot;</code> in my targets file, this is just ignored and my DLLs are copied to my bin folder during each build.</p>
<p>This is an heavy process just to achieve a DLLs extracting, now I really want to get rid of all that MsBuild and get a much simpler solution.</p>
<p>I know with newer versions of Nuget, it's now capable of extracting them natively without any help of adding custom MsBuild commands. As written <a href="https://docs.nuget.org/ndocs/guides/create-uwp-packages#adding--targets" rel="noreferrer">here</a>, C# projects don't even need a <code>targets</code> file</p>
<blockquote>
<p>Next, C++ and JavaScript projects that might consume your NuGet package need a .targets file to identify the necessary assembly and winmd files. (C# and Visual Basic projects do this automatically.)</p>
</blockquote>
<p>I kept a tab opened in my browser for several month (<a href="https://docs.nuget.org/ndocs/guides/build-for-uwp#runtimes" rel="noreferrer">original link</a>) and realize this resource has been recently removed from Nuget website. It was explaining how to use the <code>runtimes</code> folder to automatically extract natives DLLs. However I've never been able to get a successful result as it was explained. Now this page has been deleted and replaced by <a href="https://docs.nuget.org/ndocs/create-packages/native-packages" rel="noreferrer">this one</a> with so few explanations and not talking about this <code>runtimes</code> folder at all.</p>
<p>My guess is that I should use <code>runtimes</code> folder for native DLLs and the <code>lib</code> one for managed but I'm not 100% sure of that. (also should I use the <code>build</code> folder?)</p>
<p>I've tried several things (I can't recall number of attempts, as I said several months of headache...) like <a href="https://docs.nuget.org/ndocs/guides/create-uwp-packages#package-the-component" rel="noreferrer">this architecture</a> (I don't understand here what's the point of having <code>build/native</code> and also natives folders under <code>runtimes</code>)
<a href="https://i.stack.imgur.com/M5Iny.png" rel="noreferrer"><img src="https://i.stack.imgur.com/M5Iny.png" alt="enter image description here" /></a></p>
<p>I also tried to use the .NET framework version structure as described <a href="https://stackoverflow.com/a/27950347/1203116">here</a> for my managed libraries.</p>
<p><a href="https://github.com/NuGet/Home/issues/1221#issuecomment-134379269" rel="noreferrer">This</a> seems to be also part of the solution</p>
<blockquote>
<p>The architecture is ignored by the compiler when creating an assembly reference. It's a load time concept. The loader will prefer an architecture specific reference if it exists.</p>
<p>One trick you can use to produce an AnyCPU assembly is to use corflags to remove the architecture from your x86 assembly. EG: corflags /32BITREQ- MySDK.dll. Corflags is part of the .NET SDK and can be found in VS's developer command prompt.</p>
</blockquote>
<p>That's what I did, converting both x86 and x64 DLLs to <code>AnyCPU</code> (don't know if it does something for x64 DLLs but I didn't get errors) and then tried several different architectures in my Nuget package but still not working.</p>
<p>The default runtime without any entry in project.json is <code>win7-x64</code>, so I decided to explicitly specify it  just in case</p>
<pre><code>&quot;runtimes&quot;: {
    &quot;win7-x64&quot;: {}
},
</code></pre>
<p>So this is the Runtime Identifier I'm using for all my attempts in my Nuget package. However I don't care about the windows version. I would actually prefer having win-x86 or win-x64 but it seems to be an invalid value according to <a href="https://docs.microsoft.com/en-us/dotnet/articles/core/rid-catalog#using-rids" rel="noreferrer">this page</a></p>
<blockquote>
<p>Windows RIDs</p>
<p>Windows 7 / Windows Server 2008 R2</p>
<ul>
<li>win7-x64</li>
<li>win7-x86</li>
</ul>
<p>Windows 8 / Windows Server 2012</p>
<ul>
<li>win8-x64</li>
<li>win8-x86</li>
<li>win8-arm</li>
</ul>
<p>Windows 8.1 / Windows Server 2012 R2</p>
<ul>
<li>win81-x64</li>
<li>win81-x86</li>
<li>win81-arm</li>
</ul>
<p>Windows 10 / Windows Server 2016</p>
<ul>
<li>win10-x64</li>
<li>win10-x86</li>
<li>win10-arm</li>
<li>win10-arm64</li>
</ul>
</blockquote>
<p>However this <a href="https://github.com/dotnet/corefx/blob/v1.0.0-rc2/pkg/Microsoft.NETCore.Platforms/runtime.json" rel="noreferrer">Github source</a> is describing more RID so which source is right?</p>
<p>As you can see, there is so many mysteries here, mostly because of the lack of documentation or even contradictions between different docs.</p>
<p>If at least I could have a working example, then I could perform my tests to answer other questions like trying generic <code>win-x64</code> RID or see if I can include once my managed libs whatever the .NET Framework version.</p>
<p>Please pay attention to my special context: <strong>I have an ASP.NET Core project targeting the full .NET Framework</strong></p>
<p>Thanks for your answers, I'm desperate to get this simple thing working.</p>