做网站要不要服务器,wordpress 微信导航,手机 上传 Wordpress,汽车之家网页版入口原文地址#xff1a;https://www.cnblogs.com/kewei/p/16722674.html0 起因这段日子看到dotnet7-rc1发布#xff0c;我对NativeAot功能比较感兴趣#xff0c;如果aot成功#xff0c;这意味了我们的dotnet程序在防破解的上直接指数级提高。我随手使用asp.netcore-7.0模板创建…原文地址https://www.cnblogs.com/kewei/p/16722674.html0 起因这段日子看到dotnet7-rc1发布我对NativeAot功能比较感兴趣如果aot成功这意味了我们的dotnet程序在防破解的上直接指数级提高。我随手使用asp.netcore-7.0模板创建了一个默认的web程序发现aot发布出来web服务完全使用这是之前那些preview版本做不到的。想到fastgithub本质上也是基于asp.netcore-6.0框架的项目于是走上fastgithub的aot改造之路。1 改造步骤1.1 升级框架将所有项目的TargetFramework值改为7.0fastgithub使用Directory.Build.props所以我只需要在Directory.Build.props文件修改一个地方所有项目生效了。1.2 升级nuget包所有项目的nuget包进行升级像有些是6.0.x版本的如果有7.0.x-rc.x.x的更新包就升级到最新rc版本。1.3 json序列化如果您的使用JsonSerializer序列化了内部未公开的类型则需要改为JsonSerializerContext源代码生成方式比如我在想序列化下面的EndPointItem类型的实例需要如下改进private record EndPointItem(string Host, int Port);[JsonSerializable(typeof(EndPointItem[]))]
[JsonSourceGenerationOptions(WriteIndented true,PropertyNamingPolicy JsonKnownNamingPolicy.CamelCase)]
private partial class EndPointItemsContext : JsonSerializerContext
{
}var utf8Json JsonSerializer.SerializeToUtf8Bytes(endPointItems, EndPointItemsContext.Default.EndPointItemArray);2 aot发布我发布在vs上进行发布时有问题我们需要在使用cli来发布cli发布还能为我们提供更多的编译信息输出。2.1 单文件的发布命令set output./publish
if exist %output% rd /S /Q %output%
dotnet publish -c Release /p:PublishSingleFiletrue /p:PublishTrimmedtrue --self-contained -r win-x64 -o %output%/fastgithub_win-x64 ./FastGithub/FastGithub.csprojaot编译之后也是单个文件所以如果您的程序使用PublishSingleFile模式发布不能正常运行的话就不用试着aot发布了。2.2 aot发布的命令set output./publish
if exist %output% rd /S /Q %output%
dotnet publish -c Release /p:PublishAottrue /p:PublishTrimmedtrue --self-contained -r win-x64 -o %output%/fastgithub_win-x64 ./FastGithub/FastGithub.csproj我们只需要把之前的PublishSingleFile改为PublishAot他们两个不能同时设置为true。经过几分钟的满屏黄色警告之后我们终于得到aot版本的40MB左右的fastgtihub.exe迫不及待地运行了fastgithub.exe不幸的是程序运行异常Unhandled Exception: System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerExceptions StackTrace property.--- System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerExceptions StackTrace property.--- System.NotSupportedException: Org.BouncyCastle.Security.DigestUtilitiesDigestAlgorithm[] is missing native code or metadata. This can happen for code that is not compatible with trimming or AOT. Inspect and fix trimming and AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibilityat System.Reflection.Runtime.General.TypeUnifier.WithVerifiedTypeHandle(RuntimeArrayTypeInfo, RuntimeTypeInfo) 0x5bat System.Array.InternalCreate(RuntimeType, Int32, Int32*, Int32*) 0x5cat System.Array.CreateInstance(Type, Int32) 0x46at System.RuntimeType.GetEnumValues() 0x86at Org.BouncyCastle.Utilities.Enums.GetArbitraryValue(Type enumType) 0xaat Org.BouncyCastle.Security.DigestUtilities..cctor() 0x862.3 尝试解决BouncyCastleBouncyCastle是用于生成ca证书和服务器证书的第三方库在dotnet6时或以前我们没有其它库可以完成这个功能。以上的异常大概是提示了DigestUtilities这个类型的某个内部私有类型被裁剪了所以无法创建这个已裁剪掉类型的数组类型。我想到可以给项目的ItemGroup加上TrimmerRootAssembly IncludeBouncyCastle.Crypto /让这个程序集不要裁剪然后再进行新一轮aot编译不幸的是这次是编译时异常CVTRES : fatal error CVT1103: 无法读取文件 [D:\github\FastGithub\FastGithub\FastGithub.csproj]
LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 [D:\github\FastGithub\FastGithub\FastGithub.csproj]
C:\Program Files\dotnet\sdk\7.0.100-rc.1.22431.12\Sdks\Microsoft.DotNet.ILCompiler\build\Microsoft.NETCore.Native.targe
ts(349,5): error MSB3073: 命令“C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.34.31721\bin\Hostx
64\x64\link.exe obj\Release\net7.0\win-x64\native\link.rsp”已退出代码为 1123。 [D:\github\FastGithub\FastGithub\FastGithu
b.csproj]2.4 移除BouncyCastle迫于无奈我们必须移除对BouncyCastle的依赖转为使用基础库来实现证书生成这方面几乎没有任何可以查到有帮助的资料我花了整整一天来改造感兴趣证书生成的同学可以参考CertGenerator.cs。去掉BouncyCastle之后再aot发布程序可以运行起来了没有任何异常但是发现程序没有拦截任何流量。2.5 查找程序不干活的原因由于没有任何的异常输出咱也不知道是啥情况现在使用debug模式继续aot发布然后运行fastgithub.exe在vs附加到fastgithub进程下断点分析。经过一路跟踪我发现如下一个分支总是进入return逻辑:var domain question.Name;
if (this.fastGithubConfig.IsMatch(question.Name.ToString()) false)
{return;
}我想看看fastGithubConfig现在是什么值为什么总是不匹配但是经过aot之后无法发现fastGithubConfig这个局部变量而函数内的变量也不再是crl类型而是一种为调试而存在的代理类型一样可看的信息也很少。于是我加入大量的log通过log看看fastGithubConfig是什么值最后发现是配置绑定到Options的字典类型属性时绑定不成功但也没有任何异常或日志。2.6 解决配置绑定到字典的问题这个问题咱实在不知道怎么解决那就github上发起问题吧services.Configure(configuration) failure at PublishAot果然回复很积极告诉咱们目前可以在任意调用的函数加上[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(Dictionarystring, DomainConfig))]。经过这么修改之后配置绑定到Options生效了。3 后续经过这么一个实际项目aot之后我对aot有了初步的了解个人觉得aot基本可以用小型程序的发布期待到dotnet8之后NativeAot变成没有坑。