I'm building a C# .NET core application and it is targeting the
RIDs are used with .NET Core to resolve dependencies on packages. The root for this process of resolving dependencies is your project, which you explicitly tag with one or more RIDs. When building the project, you indicate which RID you are building against.
RIDs are defined in a forest of compatibility trees, where any node in a tree represents an execution environment that can support all of its children. Each RID is the root of such a tree.
Here is an example RID compatibility tree:
win10-x64 |- win10 | `- win81 | `- win8 | `- win7 | `- win | `- any | `- base `- win81-x64 |- win81 (already included above) `- win8-x64 |- win8 (already included above) `- win7-x64 |- win7 (already included above) `- win-x64 `- win (already included above)
The full graph of RID compatibility trees is defined here:
A package can supply a different implementation for every RID if necessary. When building, if I have a dependency on that package, the build process will select the implementation closest to the root of the tree. If the tree doesn't contain any RIDs supplied by the package, then the build will fail.
There is a special kind of package called a "runtime package". Runtime packages contain native binaries that be directly loaded and executed by the host operating system. As such, these packages only supply implementations for concrete OS versions: "win7-x64", for instance, but not "win7" or "win-x64", and, say, "ubuntu.16.04-x64", but not "ubuntu.16.04", "ubuntu-x64" or "linux".
Runtime packages come into play when bundling stand-alone projects. With a stand-alone project, everything needed to run the project must be included in the build output. This means the build output must include a native binary as the entrypoint for the application. That native binary is supplied by the runtime package.
So, to address your questions:
- If I specify a RID of win7-x32 will my code also run on a 64 bit Windows OS?
Yes it will, but it will run in a 32-bit process. I have verified this with an app built & published from an Ubuntu dev VM and subsequently run on Windows 10 64-bit; if the app is published against
IntPtr.Size is 4, and if it is published against
IntPtr.Size is 8. It runs either way.
win7-x32 runtime package includes a 32-bit EXE file that hosts the .NET Core runtime and then loads & runs your project, which is bundled alongside it in a DLL file with the same name.
- If I specify a RID of win7, what does it build, will it build the 32 bit version or the 64 bit version?
If you specify a RID of
win7, it will try to find native binary builds tagged with that RID, or a compatible RID, but it won't find any. The build will fail, because there is no "win7" version of the main entrypoint EXE. You must specify either 32-bit or 64-bit (and it looks like all other platforms are 64-bit only).
I have tested this specific detail, and have found that:
dotnet restore step does not fail, but also does not install a runtime for
dotnet build step succeeds in compiling the test application, but then emits this error:
Failed to make the following project runnable: helloworld (.NETCoreApp,Version=v1.1) reason: Expected coreclr library not found in package graph. Please try running dotnet restore again.
- If I specify a RID of win7, will my program run in Windows 8, 8.1, or 10?
Assuming you specify either
win7-x64, then yes. The
win7-x64 runtime package will supply an EXE entrypoint that is a 32-bit or 64-bit EXE, respectively, and those EXEs are native binaries that will run on any Windows version starting with Windows 7.
Note that there is no runtime package currently for Windows 8, Windows 8.1 or Windows 10 specifically. The compatibility graphs for newer Windows versions includes either
win7-x64, as appropriate, and so that particular runtime package ends up being used in the build, even if you target a newer RID such as
- What does the any RID do? I understand how the portable deployment can be used on multiple platforms but how can the standalone deployment (built with a RID of any) work on Linux as well as Windows? Am I misunderstanding this RID?
any RID allows a package to supply an implementation for any RID further up the chain, because all other RIDs ultimately include
base) in their compatibility tree. Runtime packages, though, do not supply any implementation for
any, and thus
any cannot be used to build stand-alone packages.
- If I specify a RID of blah I expected an error. Instead my application was built in the bin/Release/blah directory. Did it simply default to some other runtime?
Your project must be configured with
"type": "platform" in the dependency on
Microsoft.NETCore.App. As such, no stand-alone package was built, and the resolution of supporting libraries is left to runtime, at which point the RID is supplied by the actual runtime you are using to run your app, rather than by your application's build configuration.
If your project is a library, then when you try to reference it from another project, you may encounter problems because your library is only supplying an implementation for the "blah" platform, which won't be in the compatibility tree for the RID the other project is building against. If your project is an application, then
blah is being ignored.
If you reconfigure your project to produce a stand-alone package (by removing or commenting out the
"type": "platform" line in
project.json), you will find that it no longer builds, because it now has a dependency on the runtime packages, and there is no package for RID