繁体   English   中英

无法在 CSPROJ 文件中动态更改 AssemblyName

[英]Unable to change AssemblyName dynamically within the CSPROJ file

我正在使用 Visual Studio 2022 创建一个简单的 C# class 库,目标是 .NET6 和 .NET Framework 4.8.... 我一整天都在为这件事焦头烂额。

我想根据框架以不同方式命名我的程序集。 具体来说,如果它是 .NET 构建,我想将 append“.Core”添加到我的程序集名称中。

但似乎我无法利用 a.csproj 文件中的 $(TargetFramework) 宏来更改 AssemblyName 属性的值。

例如,这在使用 $(Configuration) 宏时有效:

<PropertyGroup>
    <TargetFrameworks>net6.0;net48</TargetFrameworks>
           ...
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <AssemblyName>$(MSBuildProjectName).Debug</AssemblyName>
</PropertyGroup>

但这不是:

<PropertyGroup>
    <TargetFrameworks>net6.0;net48</TargetFrameworks>
         ....
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
    <AssemblyName>$(MSBuildProjectName).Core</AssemblyName>
</PropertyGroup>

我一直在阅读类似的问题,特别是这个问题,但我不确定它是否适用于 CSPROJ 文件。 此外,答案没有提供示例; 我不清楚如何在 CSPROJ 中实现它。

可以通过在目标框架上设置条件来覆盖 AssemblyName 吗?

我收到的错误是:

NuGet package restore failed. Please see Error List window for detailed warnings and errors.

Failed to restore D:\src2\csharp\dummy1\dummy1.csproj (in 0.6 ms).
1>C:\Program Files\dotnet\sdk\7.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(267,5): error NETSDK1005: Assets file 'D:\src2\csharp\dummy1\obj\project.assets.json' doesn't have a target for 'net6.0'. Ensure that restore has run and that you have included 'net6.0' in the TargetFrameworks for your project.

1>Done building project "dummy1.csproj" -- FAILED.

1>C:\Program Files\dotnet\sdk\7.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(267,5): error NETSDK1005: Assets file 'D:\src2\csharp\dummy1\obj\project.assets.json' doesn't have a target for 'net48'. Ensure that restore has run and that you have included 'net48' in the TargetFrameworks for your project.

1>Done building project "dummy1.csproj" -- FAILED.

使用命令行工具“do.net build”和“msbuild”,项目成功(感谢@Jimmy。)。 它只在 Visual Studio 中不起作用,我开始怀疑我的问题不是重命名程序集名称。 但是 Visual Studio 中还有其他事情需要完成。

在此处输入图像描述

@Jimmy 将我指向构建工具,我怀疑这确实是一个 Nuget 问题,而不是程序集重命名问题,尽管该错误仅在尝试重命名程序集时出现...

所以我确定,即使我按照 Jimmy 能够显示的方式重命名了程序集,当我使用我们的完整解决方案(具有大量依赖项)执行此操作时,它仍然会导致问题——我不相信 Visual Studio 会在解析依赖项时能够找到我重命名的核心程序集(因为它们是项目依赖项)。

所以这就是我所做的..

  1. 我创建了 4 个构建配置:DebugFramework、Debu.NET、ReleaseFramework 和 Releas.NET。

  2. 我从 PropertyGroup 中删除了 TargetFramework。

  3. 我将其添加到每个项目文件中:

     <Choose> <When Condition="'$(Configuration)' == 'Debu.NET' OR '$(Configuration)' == 'Releas.NET'"> <PropertyGroup> <TargetFramework.net6.0-windows</TargetFramework> <AssemblyName>$(MSBuildProjectName).Core</AssemblyName> </PropertyGroup> </When> <Otherwise> <PropertyGroup> <TargetFramework.net48</TargetFramework> <AssemblyName>$(MSBuildProjectName)</AssemblyName> </PropertyGroup> </Otherwise> </Choose>

现在,当我构建时,AssemblyName 在构建开始时是已知的,并且在构建过程中不会改变。

虽然我宁愿同时执行 .NET 和 .FRAMEWORK 构建,但这种变通方法已经足够好了,并且可能更像是微软最初希望我们这样做的方式。

希望这可以帮助别人。 感谢大家的投入!

解决这个问题的最简单(也是最愚蠢)的方法是运行一些命令,根据编译需要使用这些值更新 .csproject。 例如:

给定文件 project.csproj:

<PropertyGroup>
    <TargetFrameworks>net6.0;net48</TargetFrameworks>
           ...
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <AssemblyName>$(MSBuildProjectName).Debug</AssemblyName>
</PropertyGroup>

我会跑跑:

sed -i.backup 's/(Configuration)\x27 == \x27Debug\x27/\(TargetFramework\)\x27 == \x27net6.0\x27/' project.csproj

然后运行:

sed -i.backup 's/(MSBuildProjectName).Debug/(MSBuildProjectName).Core/' project.csproj

这会将 project.csproj 转换为:

<PropertyGroup>
    <TargetFrameworks>net6.0;net48</TargetFrameworks>
           ...
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
    <AssemblyName>$(MSBuildProjectName).Core</AssemblyName>
</PropertyGroup>

我知道这不是最酷的事情(像在 devops 时间那样转换文件),但这绝对可以解决问题。

您还可以将该脚本包装到 shell ( .sh) 或 bat ( .bat) 中,然后在构建时运行它。

PS: \x27是单引号的一个scape。 sed 命令会将单引号与您要替换的字符串混合在一起。

您可以在此处找到有关 sed 的更多信息: https ://www.geeksforgeeks.org/sed-command-in-linux-unix-with-examples/

通过一些 shell 命令,您可以使用环境变量在脚本中执行此操作。

希望有帮助!

这对我来说很好。 这是我的完整测试项目文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net6.0;net48</TargetFrameworks>
  </PropertyGroup>
  <PropertyGroup Condition="'$(TargetFramework)'=='net6.0'">
    <AssemblyName>$(MSBuildProjectName).Core</AssemblyName>
  </PropertyGroup>
</Project>

我使用dotnet build -bl ,然后使用https://msbuildlog.com/查看 msbuild.binlog 文件。 我看到顶层构建启动了两个内部构建,每个构建都有一个目标框架:

来自二进制日志查看器的屏幕截图显示了 DynamicAssemblyName.csproj 的构建。目标 DispatchToInnerBuilds 已展开,任务 MSBuild 在其中展开,显示两个内部构建。第二个内部构建被展开以显示 TargetFramework 已设置为 net6.0

如果我在查看器中向上看,我可以看到内部构建的评估(id 109,如上面的屏幕截图所示)显示该值在评估期间已更新:

Evaluation 节点展开,id 109 的节点展开。突出显示的一行输出表明 $(AssemblyName) 的属性值已重新分配。

如果我是你,我会得到一个二进制日志,看看该属性是否被重新分配回默认值,也许稍后由另一个.targets 文件重新分配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM