win /任何运行时在.NET Core中意味着什么

时间:2017-01-20 14:31:23

标签: c# .net .net-core runtime-identifier

我正在构建一个C#.NET核心应用程序,它的目标是net452框架。当我发布时,我可以指定一个运行时( - runtime),如果我没有指定任何运行时它使用win7-x64(我认为那是因为那是我的机器运行的)。但是,我也可以手动指定运行时,它似乎接受我给它的任何字符串。但是,this似乎表明winany都有效。

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

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

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

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

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

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

3 个答案:

答案 0 :(得分:28)

RID与.NET Core一起用于解析对包的依赖性。解析依赖项的此过程的根是您的项目,您使用一个或多个RID明确标记该项目。在构建项目时,您可以指出要构建的RID。

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

以下是RID兼容性树的示例:

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)

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

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

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

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

[更新:从.NET Core 2.0开始,您可以为Linux-x64构建目标"所有"具有单个版本的x64版本的Linux。见https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/]

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

所以,要解决你的问题:

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

是的,但它将以32位进程运行。我已经通过app build&从Ubuntu dev VM发布,随后在Windows 10 64位上运行;如果应用是针对win7-x32发布的,则IntPtr.Size为4,如果针对win7-x64发布,则IntPtr.Size为8.它以任何一种方式运行。

win7-x32运行时包包含一个32位EXE文件,该文件承载.NET Core运行时,然后加载&运行你的项目,它与它一起捆绑在一个同名的DLL文件中。

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

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

我已经测试了这个具体细节,并且发现了:

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

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

      

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

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

假设您指定了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,例如{{1 }}

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

win10-x64 RID允许程序包为链上的任何RID提供实现,因为所有其他RID最终在其兼容性树中包含any(和any)。但是,运行时包不提供base的任何实现,因此any不能用于构建独立包。

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

您的项目必须在any的依赖项中使用"type": "platform"进行配置。因此,没有构建独立的包,并且支持库的解析留给了运行时,此时RID由您用来运行应用程序的实际运行时提供,而不是由您的应用程序提供。构建配置。

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

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

答案 1 :(得分:16)

我相信OP中链接的official documentation提供了所有必要的信息。

首先要做的事情

  

什么是RID?

     

RID是Runtime IDentifier的缩写。 RID用于标识将运行应用程序或资产(即程序集)的目标操作系统。

     

重要的是要注意RID实际上是不透明的字符串。这意味着他们必须完全匹配使用它们才能工作的操作

这也引自GitHub

  

RID是一个标识平台的不透明字符串。 RID通过"导入"与其他RID有关系。另一个RID。以这种方式,RID是兼容RID的有向图。

     

最佳RID考虑部分RID图:

"any": {},

"win": {
    "#import": [ "any" ]
},
"win-x86": {
    "#import": [ "win" ]
},
"win-x64": {
    "#import": [ "win" ]
},
"win7": {
    "#import": [ "win" ]
},
"win7-x86": {
    "#import": [ "win7", "win-x86" ]
},
"win7-x64": {
    "#import": [ "win7", "win-x64" ]
}
     

这可以被视为有向图,如下所示:

win7-x64    win7-x86
   |   \   /    |
   |   win7     |
   |     |      |
win-x64  |  win-x86
      \  |  /
        win
         |
        any
     

因此,在评估win7-x64时,最好的RID是:win7-x64,   win7win-x64winany同样,在评估时   win-x64win-x64winany请注意win7之前   win-x64由于导入前win7的导入而导致   文档顺序为win-x64

那就是说,引用runtime.json on the CoreFX repo.

  

如果您使用此文件,您会注意到某些RID具有" #import"他们的陈述。这些语句是兼容性声明。这意味着其中包含导入的RID的RID可以是恢复该RID的包的目标。

仅提取相关部分,

  

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

"base": {
},

"any": {
    "#import": [ "base" ]
},
...
"win": {
    "#import": [ "any" ]
},
...
"win7": {
        "#import": [ "win" ]
    },
"win7-x86": {
    "#import": [ "win7", "win-x86" ]
},
"win7-x64": {
    "#import": [ "win7", "win-x64" ]
},
...
  

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

它将构建一个可以在两个平台上运行的通用版本。请参阅上面的可视化。

  

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

是。基于引用版本的导入。

"win8": {
    "#import": [ "win7" ]
},
"win8-x86": {
    "#import": [ "win8", "win7-x86" ]
},
"win8-x64": {
    "#import": [ "win8", "win7-x64" ]
},
"win8-arm": {
    "#import": [ "win8" ]
},

"win81": {
    "#import": [ "win8" ]
},
"win81-x86": {
    "#import": [ "win81", "win8-x86" ]
},
"win81-x64": {
    "#import": [ "win81", "win8-x64" ]
},
"win81-arm": {
    "#import": [ "win81", "win8-arm" ]
},

"win10": {
    "#import": [ "win81" ]
},
"win10-x86": {
    "#import": [ "win10", "win81-x86" ]
},
"win10-x64": {
    "#import": [ "win10", "win81-x64" ]
},
  

4)any RID做了什么?

这意味着构建与any支持的平台兼容,并且它可以成为恢复任何RID的包的目标。

  

5)如果我指定一个blah的RID,我预计会出错。相反,我的应用程序是在bin/Release/blah directory中构建的。它只是默认为其他运行时吗?

引用表单文档:

  

所有RID最终都会映射回根any RID。

最后,再次从文档中注意

  

虽然它们看起来很容易使用,但有一些特殊的东西   关于在使用它们时必须记住的RID:

     
      
  • 它们是不透明的字符串,应该被视为黑盒子      
        
    • 您不应以编程方式构建RID
    •   
  •   
  • 您需要使用已为平台和此定义的RID   文件显示
  •   
  • RID确实需要具体,所以不要这样做   从实际RID值中假设任何东西;请咨询这个   用于确定给定平台所需的RID的文档
  •   

答案 2 :(得分:4)

在.NET Core 2.0 下,足以构建以下目标:

  • linux-x64,linux-arm
  • win-x64,win-x86
  • OSX-64

请参阅https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/