.NET 5.中PlatformTarget和RuntimeIdentifier之间的关系



我对.NET 5中RuntimeIdentifier和PlatformTarget之间的关系感到困惑。我的.NET 5 C#项目运行和发布良好,但PlatformTarget是"AnyCPU",RuntimeIdentifier是"win-x64"。

根据微软的文档,RuntimeIdentifier是";用于识别应用程序运行的目标平台";。https://learn.microsoft.com/en-us/dotnet/core/rid-catalog这不是"平台目标"应该做的吗?

我试着使用我以前见过的RuntimeIdentifers(复数)(也许是.NET Core 3?),但该项目没有使用以下代码编译:

<RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>

来自我当前的项目文件:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>   -> RuntimeIdentifier is required since SelfContained is 'true'
...
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
...
</Project>

;AnyCPU";意味着它将具有兼容32位和64位的二进制文件。这意味着它不意味着对32位和64位都是特定的;AnyCPU";主要用于较旧的.NET Framework项目,而不常用于主要用于.NET Core项目的SDK项目样式。

这些.NET核心项目包括单一目标的.NET核心项目或多目标的.NET内核项目,例如具有多目标的项目(通常称为TFM)。

由于.NET 5.0,TFM可以是跨平台的TFM,如net5.0或.NET 5.0目标,带有特定的操作系统,如net5.0-windowsnet5.0-ios。如果要指定在Windows上运行的64位.NET 5.0类库,则必须同时指定TFM和RuntimeIdentifier(通常称为RID)。

因此,我们不应该使用较老的";AnyCPU";与组合的Conditional";释放|AnyCPU";。默认情况下,任何没有RID的TFM总是与这些SDK项目模型中有AnyCPU相同。

例如,针对64位和32位的Windows上的.NET 5.0:

<PropertyGroup>
<TargetFramework>net5.0-windows;</TargetFramework>
<RuntimeIdentifier>win-x64;win-x86</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
</PropertyGroup>

SDK项目具有属性SDK="此SDK将驱动您的项目的引用解析。

我建议您删除那些具有旧"的PropertyGroup;释放|AnyCPU";或";调试|AnyCPU";组合,因为这些组合的MSBuild项目语法与任何.NET Core SDK项目模型都不相关。

需要注意的一点是,当您有多个RID(如上面示例中的RID)时,必须为您支持的每个RID运行publish。

因此,为了同时拥有64位和32位,您必须为每个RID分别发布

所以你必须运行这些:

dotnet publish yourproject.csproj -r win-x64 
dotnet publish yourproject.csproj -r win-x86 

另请参阅关于发布单个文件可执行文件的官方文档:https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file

的确,一堆属性很难理解(Platform、PlatformTarget、TargetFramework(Moniker)和RuntimeIdentifier)。以下是我目前对这些性质的看法——请记住,由于我的实验结果,我仍然有问题)。

Platform、Platforms和PlatformTarget:这些属性是同义词(需要Platforms复数才能容纳多个平台说明符),指的是位/CPU体系结构,如AnyCPU、x86、x64和Arm。我一直认为"硬件";对于此属性。

TargetFramework:这指定应用程序要运行的.NET Framework API版本(net48、net5.0、wp(windowsphone)、netcore、netcoreapp2.1等)。其中一些是跨平台的(跨硬件?)。

RuntimeIdentifier:运行时说明符是堆栈的跨平台粘合部分,位于抽象级别堆栈中:app->框架->运行时->站台如果您的库同时配置为x86和x64,则msbuild会将变体发布到bin/debug/framework/win-x86/和bin/debug/framework/win-x64/(因此,win-x86和win-64以及其他运行时在输出文件夹树中是同级的)。

对于您使用的每个运行时,您必须发布/生成一次项目(使用不同的属性值)。

对于最初的问题,您可以看到AnyCPU是一个平台说明符,RID是运行时标识符。为了方便通信,RID名称通常在名称中包含x86/x64,但这些字符串并不指定平台。只有Platform说明符才能指定平台。

在操作中,您可以指定Platform AnyCPU来构建应用程序(指示应用程序二进制文件适用于x86、x64、arm等),然后在发布操作中使用特定的运行时(将为发布的二进制文件分配32/64位等)。

如果没有提供MSBuild重写参数,则我的NET5项目文件需要同时定义Platform和TargetFramework。MSBuild假定win-x64为我的项目的运行时,这些项目定义了Platform=AnyCPU和TargetFramework=net5.0-windows7.0。

值得一提的是,MSBuild可以从三个地方获取其属性:MSBuild项目文件;Visual Studio对话框工作表(可能覆盖项目文件值;以及MSBuild命令行(覆盖项目文件的值)。

最新更新