我有一个可执行文件需要与 Linux 和 Windows 兼容。一项特定功能使用需要 Winforms 的第三方库,因此它需要 Windows 目标框架。我可以在 Linux 版本上禁用该功能。
我已将该功能分离到一个单独的库项目中,并以 net8.0-windows 作为目标框架。
在我的可执行文件中,我有一个条件项目引用,如果操作系统是 Windows,则仅引用 Windows 库:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<Optimize>true</Optimize>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<ErrorReport>prompt</ErrorReport>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<ItemGroup Condition="'$(IsWindows)'=='true'">
<ProjectReference Include="..\WindowsLibrary.csproj" />
</ItemGroup>
我遇到的问题是目标框架。我认为我需要指定两个支持的目标框架:
<TargetFrameworks>net8.0;net8.0-windows</TargetFrameworks>
在我的 CI/CD 管道中,我将使用
-f
上的 dotnet publish
选项传递目标框架。
但我无法让它发挥作用。似乎总是用net8.0构建,然后抱怨Windows库不兼容。
我已将其添加到可执行文件的项目文件中,以打印使用的目标框架:
<Target Name="Print used target framework" BeforeTargets="CollectPackageReferences">
<Message Importance="High" Text="TargetFramework: $(TargetFramework)" />
</Target>
这是我使用的命令和输出:
dotnet publish .myapp.csproj --configuration Release -f "net8.0-windows" --runtime win-x64 --output ./MyApp --no-self-contained
MSBuild version 17.8.3+195e7f5a3 for .NET
Determining projects to restore...
TargetFramework:
TargetFramework: net8.0
TargetFramework: net8.0-windows
C:\myapp.csproj : error NU1201: Project WindowsLibrary is not compatible with net8.0 (.NETCoreApp,Version=v8.0). Project WindowsLibrary supports: net8.0-windows7.0 (.NETCoreApp,Version=v8.0)
C:\myapp.csproj : error NU1201: Project WindowsLibrary is not compatible with net8.0 (.NETCoreApp,Version=v8.0) / win-x64. Project WindowsLibrary supports: net8.0-windows7.0 (.NETCoreApp,Version=v8.0)
那么为什么它不断尝试为 net8.0 构建?
关键是确保添加此包的单个元素或包含它的
Condition
上有一个 <ItemGroup>
。这可以就像Condition="'$(TargetFramework)'=='net8.0-windows'"
一样简单;你可以做更复杂和细致的 Condition
结构,但很快就很难确定是否包含某些内容。