.NET Core RuntimeIdentifier和TargetFramework的区别

44

有人可以解释一下 csproj 文件中这两个的目的吗?(VS2017)

<TargetFramework>netstandard1.6</TargetFramework>
<RuntimeIdentifier>win7</RuntimeIdentifier>

我刚从VS2015迁移,现在无法发布我的Web API,因为看起来我应该只使用一个目标框架。此外,我无法指定多个RID。 所有这些变化让我感到沮丧。什么都无法从头开始运行,我必须一次又一次地克服问题。
我只想在Windows上开发我的Web API,在此处运行xUnit测试,然后将Web API部署到Linux(Ubuntu)服务器上运行。 我应该在csproj文件的这两个参数中放入什么? 非常感谢提供解释的链接。
更新1
我有一个带有引用的.NET Core库的Web API。所有东西都从VS2015迁移过来。现在在根项目中,我有 netcoreapp1.1;net461。当我通过VS2017进行发布时,我收到错误消息:
C:\Program Files\dotnet\sdk\1.0.3\Sdks\Microsoft.NET.Sdk\buildCrossTargeting\Microsoft.NET.Sdk.targets(31,5): error : 未指定目标框架不支持“Publish”目标。当前项目针对多个框架,请为发布的应用程序指定框架。
但是我在发布中指定了目标框架为netcoreapp1.1。 好的。然后我根据下面的建议更新了我的csproj文件,添加了<PropertyGroup Condition="$(TargetFramework)'=='netcoreapp1.1'"> <RuntimeIdentifier>ubuntu.16.10-x64</RuntimeIdentifier> </PropertyGroup>。 但是现在我甚至无法构建应用程序,出现错误:

5>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.targets(92,5): error : Assets file '\obj\project.assets.json' doesn't have a target for '.NETCoreApp,Version=v1.1/ubuntu.16.10-x64'. Ensure you have restored this project for TargetFramework='netcoreapp1.1' and RuntimeIdentifier='ubuntu.16.10-x64'.

我只想使用VS2017在Windows 8.1/Windows 7上进行开发,并部署到Ubuntu 16.10上。 我做错了什么?
我有8个解决方案中的项目。其中3个是xUnit测试。因此我们有5个项目。这5个项目中有4个是类库,1个是我的Web应用程序。 所有这4个类库都具有以下内容:
<TargetFrameworks>netstandard1.6;net461</TargetFrameworks>    
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
    <Reference Include="System" />
    <Reference Include="Microsoft.CSharp" />
</ItemGroup>

我的网络应用程序:
<TargetFrameworks>netcoreapp1.1;net461</TargetFrameworks>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
    <Reference Include="System" />
    <Reference Include="Microsoft.CSharp" />
  </ItemGroup>

如何发布我的网页应用?
2个回答

35

<TargetFramework>(或者当你要有多个目标时,例如net451、一个或多个netstandard1.x等时,使用<TargetFrameworks>)。每个<TargetFramework> / <TargetFrameworks>条目都会创建一组程序集,并放置在bin\Debug\<targetframeworkid>文件夹中。

当你想在.NET Core中使用不同的库(因为你使用的库只能与完整的.NET Framework,如4.5.1配合使用)或者从.NET Core中移除这个功能时,这非常有用。

它既用于构建也用于NuGet还原。例如,你不能在.NET Core项目中使用仅支持net451的库(例如netstandard 1.1),但你可以在net451项目中使用netstandard1.1

<RuntimeIdentifier> / <RuntimeIdentifiers>则主要用于NuGet。它告诉NuGet你需要哪些包。例如,如果你想针对Linux、Mac和Windows进行定位,则某些程序集需要本地库(例如加密。在Windows上将使用CryptoAPI,但在Linux和Mac上则需要OpenSSL)。这包括非托管dll和*.so(Linux)文件。

例如,<RuntimeIdentifiers>win7-x64;win7-x86;ubuntu.16.10-x64</RuntimeIdentifiers>会使NuGet为win7(包括x64和x86版本)以及仅x64的ubuntu还原包。这是必需的,因为当你在Windows上工作时,你也需要下载这些本地库,以便使用dotnet publish部署/打包它们。

这里有一个小问题:当你在<TargetFramework><TargetFrameworks>中引用了完整的.NET Framework时,你必须指定单个<RuntimeIdentifier>(单数,而不是复数的<RuntimeIdentifiers>),否则你将会收到错误信息。

例如:

<PropertyGroup>
    <TargetFrameworks>netstandard1.0;net451</TargetFrameworks>
    <RuntimeIdentifiers>win7-x64;win7-x86;ubuntu.16.10-x64</RuntimeIdentifiers>    
</PropertyGroup>

<!-- This entry will only be used for the .NET Framework 4.5.1 output -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net451'">
    <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
</PropertyGroup>

3
使用 .Net Standard 时,"<TargetFrameworks>netstandard1.0;net451</TargetFrameworks>" 是不必要的。您正在使用许多过时的做法。 - J. Doe
@Tseng 感谢您的帮助,但它仍然不起作用。我运行 dotnet publish --runtime ubuntu.16.10-x64 并得到相同的错误。正如我所说,我的根应用程序(web-app)针对 netcoreapp1.1;net461。我没有使用 net451,只在我的5个项目中使用了3个项 netcoreapp1.1 net461 netstandard1.6 - Alezis
@Alezis,不如直接使用netstandard1.6,然后执行dotnet publish -c release -r ubuntu.16.10-x64 - J. Doe
1
很不幸,@J.Doe,在许多情况下,仅使用netstandard是不够的。例如,如果您正在引用System.Drawing.Common库,则必须分别针对net462(或更高版本)和netstandard进行交叉编译(截至2018年11月)。 - Jaykul
我正在使用RuntimeIdentifier和PublishSingleFile来创建.exe文件,以便在开发过程中进行轻松测试。有没有一种方法可以说RuntimeIdentifier是我们编译的当前平台?我想避免硬编码它们。 - dashesy
显示剩余2条评论

8
RID是运行时标识符的缩写。RID用于标识应用程序或资产(即程序集)将在其中运行的目标操作系统。它们看起来像这样:“ubuntu.14.04-x64”,“win7-x64”,“osx.10.11-x64”。对于具有本机依赖项的包,它将指定可以恢复该包的平台。详情请参阅文档
首先从“win7”更改为正确的RID,例如“win7-x64”或“win7-x86”。接下来添加其他RID,例如ubuntu。
<PropertyGroup>
    <TargetFramework>netstandard1.6</TargetFramework>
    <RuntimeIdentifier>win7-x64;ubuntu.16.10-x64</RuntimeIdentifier>
</PropertyGroup>

目标框架看起来很不错。欲了解更多,请阅读文档


3
应该是RuntimeIdentifiers吧?RuntimeIdentifier只允许一个ID。 - CharithJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接