我对.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-windows
或net5.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命令行(覆盖项目文件的值)。