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

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

问题描述

我正在构建一个C#.NET核心应用程序,它的目标是 net452 框架。发布时,我可以指定一个运行时(--runtime),如果不指定任何运行时,它会使用 win7-x64 (我认为那是因为机器正在运行)。但是,我也可以手动指定运行时,它似乎可以接受我提供的任何字符串。但是, RID目录似乎都建议< c $ c> win 以及 any 是有效的。



更新:我没有很好的答案,所以我将澄清我的问题并添加赏金。我也曾在ASP.NET核心论坛上提问,但没有得到答复。


  1. 如果我将RID指定为 win7-x32 我的代码也可以在64位Windows操作系统上运行吗?


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


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


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


  5. 如果我将RID指定为 blah ,则可能会出现错误。相反,我的应用程序构建在 bin / Release / blah 目录中。



解决方案

RID与.NET Core解决包上的依赖关系。解决依赖关系的过程的根源是您的项目,您在项目中显式标记了一个或多个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,则构建将失败。



有一种特殊的软件包称为运行时软件包。运行时程序包包含本机二进制文件,这些二进制文件可以由主机操作系统直接加载并执行。因此,这些软件包仅提供具体OS版本的实现:例如, win7-x64,但不提供 win7或 win-x64,例如 ubuntu.16.04-x64,但不提供 ubuntu。 .16.04, ubuntu-x64或 linux。



[更新::从.NET Core 2.0开始,您可以针对Linux-x64以单一构建为目标,以全部 x64版本的Linux为目标。请参阅 https://博客。 msdn.microsoft.com/dotnet/2017/08/14/announcing-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位版本?


如果将RID指定为 win7 ,它将尝试查找标记有该RID或兼容RID的本机二进制版本。找不到。生成将失败,因为没有主入口点EXE的 win7版本。您必须指定32位或64位(并且看起来所有其他平台都仅是64位)。



我已经测试了此特定细节,并具有发现:




  • dotnet恢复步骤没有失败,但是也不会为<$​​ c $ c> win7 (或 win10 )安装运行时。


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



    < blockquote>

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







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


假设您指定 win7-x86 win7-x64 , 好的。 win7-x86 win7-x64 运行时程序包将提供32位或64位的EXE入口点。 EXE,并且这些EXE是本机二进制文件,将在Windows 7开始的任何Windows版本上运行。



请注意,Windows 8当前没有运行时程序包,专门用于Windows 8.1或Windows 10。 Windows较新版本的兼容性图包括 win7-x86 win7-x64 (视情况而定),即使您以较新的RID为目标,例如 win10-x64 ,运行库程序包最终仍会在构建中使用。



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


任何 RID允许程序包为链上的任何RID提供实现,因为所有其他RID最终都包括 any (和 base )。但是,运行时程序包不提供 any 的任何实现,因此 any 不能用于独立构建



  1. 如果我指定RID为blah,则可能会出现错误。相反,我的应用程序构建在bin / Release / blah目录中。


您的项目必须配置为类型:平台 依赖于 Microsoft.NETCore.App 。因此,没有构建任何独立的程序包,并且支持库的分辨率由运行时决定,这时RID由您用来运行应用程序的实际运行时提供,而不是由应用程序的构建配置提供。 / p>

如果您的项目是一个库,那么当您尝试从另一个项目中引用它时,您可能会遇到问题,因为您的库仅提供 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 /任何运行时”是什么意思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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