.NET Core 中的 win/any 运行时是什么意思 [英] What does the win/any runtime mean in .NET Core

查看:17
本文介绍了.NET Core 中的 win/any 运行时是什么意思的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个 C# .NET 核心应用程序,它面向 net452 框架.当我发布时,我可以指定一个运行时 (--runtime),如果我没有指定任何运行时,它将使用 win7-x64(我认为这是因为我的机器正在运行).但是,我也可以手动指定运行时,它似乎接受我提供的任何字符串.但是,RID 目录 似乎暗示了 winany 都是有效的.

更新:我没有任何好的答案,所以我将澄清我的问题并增加悬赏.我也在 ASP.NET 核心论坛上问过,但没有得到回应.

  1. 如果我指定 win7-x32 的 RID,我的代码是否也会在 64 位 Windows 操作系统上运行?

  2. 如果我指定 win7 的 RID,它会构建什么,它会构建 32 位版本还是 64 位版本?

  3. 如果我指定了 win7 的 RID,我的程序会在 Windows 8、8.1 或 10 中运行吗?

  4. any RID 有什么作用?我了解如何在多个平台上使用可移植部署,但独立部署(使用 any 的 RID 构建)如何在 Linux 和 Windows 上工作?我误解了这个 RID 吗?

  5. 如果我指定 blah 的 RID,我预计会出现错误.相反,我的应用程序是在 bin/Release/blah 目录中构建的.它是否只是默认为其他运行时?

解决方案

RID 与 .NET Core 一起使用来解决对包的依赖关系.这一解决依赖关系的过程的根是您的项目,您明确地用一个或多个 RID 标记它.构建项目时,请指明您正在构建的 RID.

RID 定义在兼容性树的森林中,其中树中的任何节点表示可以支持其所有子节点的执行环境.每个 RID 都是这种树的根.

这是一个 RID 兼容性树示例:

win10-x64|- WIN10|`-win81|`-win8|`-win7|`- 赢|`- 任何|`- 基地`- win81-x64|- win81(上面已经包含了)`- win8-x64|- win8(上面已经包含了)`- win7-x64|- win7(上面已经包含了)`-win-x64`- 赢(上面已经包括了)

此处定义了 RID 兼容性树的完整图:

https://github.com/dotnet/runtime/blob/master/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json

如有必要,包可以为每个 RID 提供不同的实现.构建时,如果我依赖于该包,构建过程将选择最接近树根的实现.如果树不包含包提供的任何 RID,则构建将失败.

有一种特殊的包叫做运行时包".运行时包包含由主机操作系统直接加载和执行的本机二进制文件.因此,这些包仅提供具体操作系统版本的实现:例如,win7-x64",但不提供win7"或win-x64",例如ubuntu.16.04-x64",但不提供ubuntu".16.04"、"ubuntu-x64" 或 "linux".

[更新:从 .NET Core 2.0 开始,您可以针对 Linux-x64 构建以通过单个构建针对所有"x64 版本的 Linux.请参阅 https://blogs.msdn.microsoft.com/dotnet/2017/08/14/annoucing-net-core-2-0/ ]

运行时包在捆绑独立项目时发挥作用.对于独立项目,运行项目所需的一切都必须包含在构建输出中.这意味着构建输出必须包含一个本地二进制文件作为应用程序的入口点.该原生二进制文件由运行时包提供.

所以,解决您的问题:

<块引用>

  1. 如果我指定 RID 为 win7-x32,我的代码是否也能在 64 位 Windows 操作系统上运行?

是的,它会,但它将在 32 位进程中运行.我已经通过构建的应用程序验证了这一点从 Ubuntu 开发 VM 发布,随后在 Windows 10 64 位上运行;如果应用是针对 win7-x32 发布的,那么 IntPtr.Size 是 4,如果它是针对 win7-x64 发布的,那么 IntPtr.Size 是 8.它以任何一种方式运行.

win7-x32 运行时包包含一个 32 位 EXE 文件,该文件托管 .NET Core 运行时然后加载 &运行您的项目,该项目捆绑在同名的 DLL 文件中.

<块引用>

  1. 如果我指定一个 RID 为 win7,它会构建什么,它会构建 32 位版本还是 64 位版本?

如果您指定 win7 的 RID,它会尝试查找使用该 RID 或兼容 RID 标记的本机二进制构建,但找不到任何.构建将失败,因为主入口点 EXE 没有win7"版本.您必须指定 32 位或 64 位(看起来所有其他平台都只有 64 位).

我测试了这个特定的细节,并发现:

  • dotnet restore 步骤不会失败,但也不会为 win7(或 win10)安装运行时.

  • dotnet build 步骤成功编译测试应用程序,但随后发出此错误:

    <块引用>

    无法使以下项目可运行:helloworld (.NETCoreApp,Version=v1.1) 原因:在包图中找不到预期的 coreclr 库.请再次尝试运行 dotnet restore.

<块引用>

  1. 如果我指定 RID 为 win7,我的程序会在 Windows 8、8.1 或 10 中运行吗?

假设您指定了 win7-x86win7-x64,则是.win7-x86win7-x64 运行时包将分别提供一个 32 位或 64 位 EXE 的 EXE 入口点,这些 EXE 是本机二进制文件将在从 Windows 7 开始的任何 Windows 版本上运行.

请注意,目前没有专门针对 Windows 8、Windows 8.1 或 Windows 10 的运行时包.较新的 Windows 版本的兼容性图包括 win7-x86win7-x64,视情况而定,因此特定的运行时包最终会在构建中使用,即使您的目标是更新的 RID,例如 win10-x64.

<块引用>

  1. any RID 有什么作用?我了解如何在多个平台上使用可移植部署,但独立部署(使用任何 RID 构建)如何在 Linux 和 Windows 上工作?我误解了这个 RID 吗?

any RID 允许包为链上的任何 RID 提供实现,因为所有其他 RID 最终都包含 any(和 basecode>) 在它们的兼容性树中.但是,运行时包不为 any 提供任何实现,因此 any 不能用于构建独立包.

<块引用>

  1. 如果我指定了一个 blah 的 RID,我预计会出现错误.相反,我的应用程序是在 bin/Release/blah 目录中构建的.它是否只是默认为其他运行时?

您的项目必须在 Microsoft.NETCore.App 的依赖项中使用 "type": "platform" 进行配置.因此,没有构建独立的包,支持库的解决方案由运行时决定,此时 RID 由您用来运行应用程序的实际运行时提供,而不是由应用程序的构建配置提供.

如果您的项目是一个库,那么当您尝试从另一个项目中引用它时,您可能会遇到问题,因为您的库仅提供blah"平台的实现,而该实现不会出现在兼容树中另一个项目正在构建的 RID.如果您的项目是一个应用程序,那么 blah 将被忽略.

如果您重新配置项目以生成独立包(通过删除或注释掉 project.json 中的 "type": "platform" 行),你会发现它不再构建了,因为它现在依赖于运行时包,而且没有 RID blah 的包.

I'm building a C# .NET core application and it is targeting the net452 framework. When I publish I can specify a runtime (--runtime), if I don't specify any runtime it uses win7-x64 (I assume that is because that is what my machine is running). However, I can also manually specify the runtime and it seems to accept any string I give it. However, the RID catalog seems to suggest both win as well as any are valid.

UPDATE: I don't have any good answers so I'm going to clarify my questions and add a bounty. I've also asked on the ASP.NET core forums but gotten no response.

  1. If I specify a RID of win7-x32 will my code also run on a 64 bit Windows OS?

  2. If I specify a RID of win7, what does it build, will it build the 32 bit version or the 64 bit version?

  3. If I specify a RID of win7, will my program run in Windows 8, 8.1, or 10?

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

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

解决方案

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:

https://github.com/dotnet/runtime/blob/master/src/libraries/pkg/Microsoft.NETCore.Platforms/runtime.json

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".

[Update: as of .NET Core 2.0, you can build for Linux-x64 to target "all" x64 versions of Linux with a single build. See https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/ ]

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:

  1. 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 win7-x32, then IntPtr.Size is 4, and if it is published against win7-x64, then IntPtr.Size is 8. It runs either way.

The 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.

  1. 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:

  • The dotnet restore step does not fail, but also does not install a runtime for win7 (or win10).

  • The 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.

  1. If I specify a RID of win7, will my program run in Windows 8, 8.1, or 10?

Assuming you specify either win7-x86 or win7-x64, then yes. The win7-x86 or 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-x86 or 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 win10-x64.

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

The any RID allows a package to supply an implementation for any RID further up the chain, because all other RIDs ultimately include any (and 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.

  1. 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 blah.

这篇关于.NET Core 中的 win/any 运行时是什么意思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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