如何判断.NET 4.8项目需要随包分发哪些系统DLL
解答
1. 三个DLL的归属判定
Microsoft.Win32.Registry、System.Security.Principal.Windows:不属于.NET Framework 4.8 自带程序集,二者是.NET Standard 2.0 兼容垫片,用于实现跨框架(.NET Framework/.NET Core/.NET 5+)的API兼容,默认不会随.NET Framework 4.8 安装写入系统GAC。System.ServiceProcess.ServiceController:属于.NET Framework 4.8 自带的核心框架程序集,.NET 4.8 安装时会自动将其写入系统GAC。
2. DLL被自动复制到bin目录的原因
如果你的项目引用了任意支持.NET Standard的第三方包,或是手动开启了项目的.NET Standard兼容支持,NuGet会自动引入上述两个垫片类库,且默认将CopyLocal属性设为true,构建时就会自动输出到bin目录。System.ServiceProcess.ServiceController被输出到bin目录,大概率是该引用的「本地复制」属性被手动改为了true,该框架自带程序集默认CopyLocal属性为false。
3. 分发建议
System.ServiceProcess.ServiceController:无需随发布包分发,只要终端用户设备安装了.NET Framework 4.8 即可正常加载。你可以在项目引用列表中找到该引用,将「本地复制」属性改为False,后续构建就不会再输出该DLL到bin目录。Microsoft.Win32.Registry、System.Security.Principal.Windows:必须随发布包分发。.NET 4.8 默认安装不会包含这两个程序集,直接删除的话,若终端用户设备没有其他程序将这两个DLL写入GAC,会直接触发程序集加载失败的异常。
4. C# 编程判断DLL是否属于.NET 4.8 自带内容的方法
核心判断逻辑为验证程序集的微软官方签名,同时校验该程序集是否存在于.NET Framework 4.8 的默认安装目录中,参考实现代码如下:
using System; using System.Linq; using System.Reflection; using System.IO; public static class DotNet48AssemblyChecker { // .NET Framework 4.8 32位 默认安装路径 private const string DotNet48x86Path = @"C:\Windows\Microsoft.NET\Framework\v4.0.30319"; // .NET Framework 4.8 64位 默认安装路径 private const string DotNet48x64Path = @"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"; // 微软.NET Framework 官方程序集公钥标记 private static readonly byte[] MsFrameworkPublicKeyToken = { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }; public static bool IsBuiltInDotNet48Assembly(string dllFilePath) { try { var assemblyName = AssemblyName.GetAssemblyName(dllFilePath); // 先校验是否为微软官方签名的程序集 var assemblyPublicKeyToken = assemblyName.GetPublicKeyToken(); if (!assemblyPublicKeyToken.SequenceEqual(MsFrameworkPublicKeyToken)) { return false; } // 再校验是否存在于.NET 4.8 官方安装目录 var dllFileName = Path.GetFileName(dllFilePath); return File.Exists(Path.Combine(DotNet48x86Path, dllFileName)) || File.Exists(Path.Combine(DotNet48x64Path, dllFileName)); } catch { // 无法读取程序集信息时直接返回false return false; } } }
注:该方法仅适用于标准.NET Framework 4.8 环境的校验,.NET Standard 兼容垫片类库即使有微软官方签名,也不会出现在.NET 4.8 安装目录中,会返回非自带的判定结果,符合发布包筛选移除的需求。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

