上海做网站联系电话,周口网站建设电话,百度关键词怎么优化,深圳商城网站设计推荐在一些 Windows 7 系统上#xff0c;根据 dotnet 官方文档#xff0c;需要安装上 KB2533623 补丁#xff0c;才能运行 dotnet core 或 .NET 5 等应用。尽管非所有的设备都需要安装此#xff0c;但这也让应用的分发不便#xff0c;安装包上都需要带上补丁给用户安装。此补丁… 在一些 Windows 7 系统上根据 dotnet 官方文档需要安装上 KB2533623 补丁才能运行 dotnet core 或 .NET 5 等应用。尽管非所有的设备都需要安装此但这也让应用的分发不便安装包上都需要带上补丁给用户安装。此补丁同时也要求安装完成之后重启系统这对用户端来说也是较不方便。本文来聊聊为什么 dotnet core 一系的框架依赖于此补丁特别感谢 lsj 给我讲解 Win32 调用部分的知识和帮我调查具体的原因我只是记录的工具人补丁开始之前先来理一下所需补丁的情况不想看补丁细节还请跳到下文主题这章。准确来说在当前 2021.12.25 官方推荐 Win7 系统打上的补丁是 KB3063858 补丁KB3063858: MS15-063Windows 内核中的漏洞可能允许特权提升2015 年 6 月 9 日 此安全更新可解决 Windows 中的一个漏洞。如果用户访问包含特殊设计的文件的网络共享或指向网络共享的网站时此漏洞可能允许特权提升。但是在所有情况下攻击者都无法强制用户访问此类网络共享或网站。也有伙伴推荐给我的是安装 KB4457144 补丁。但是 KB4457144 补丁太大了包含太多内容带上这个补丁没什么优势KB4457144: 2018 年 9 月 11 日 - KB4457144月度汇总在 GitHub 上的 Security update KB2533623 no longer available · Issue #20459 · dotnet/docs 讨论上有大佬表示 KB3063858 或 KB4457144 包含了 KB2533623 补丁内容The thread claims that KB2533623 is superseded by KB3063858 or KB4457144. https://github.com/dotnet/docs/issues/20459#issuecomment-689513876值得一说的是对需要安装 KB3063858 补丁的系统来说大多数都需要额外加上证书参阅 https://www.microsoft.com/pkiops/Docs/Repository.htm 因此我认为对于客户端分发来说打上 KB2533623 补丁似乎更好。但是 KB2533623 当前被微软下架了请看 Security update KB2533623 no longer available · Issue #20459 · dotnet/docs这是 KB2533623 的下载地址: http://www.microsoft.com/download/details.aspx?familyidc79c41b0-fbfb-4d61-b5d8-cadbe184b9fc另外在刚推送 dotnet core 3.0 的预览版本时有伙伴在 WPF 官方仓库反馈说需要加上 KB2999226 补丁。此 KB2999226 补丁是 Windows 中的 Universal C Runtime 更新 的内容参阅 https://github.com/dotnet/wpf/issues/2009#issuecomment-543872453也许可以使用 runtime.win7-x64.Microsoft.NETCore.Windows.ApiSets NuGet 库 代替 KB2999226 补丁内容只需要将 api-xxxxx.dll 这些文件拷贝到输出路径即可。或者是解包 VC 2015 的分发包里的文件将 api-xxxxx.dll 和 ucrtbase.dll 拷贝到输出路径即可因此对于客户端分发来说似乎采用 KB2533623 最小补丁然后在输出路径上拷贝好 api-xxxxx.dll 这些文件到输出路径是最佳方法下载地址KB2533623 x86MD5EDF1D538C85F24EC0EF0991E6B27F0D7SHA125BECC0815F3E47B0BA2AE84480E75438C119859KB2533623 x64MD50A894C59C245DAD32E6E48ECBDBC8921SHA18A59EA3C7378895791E6CDCA38CC2AD9E83BEBFFKB3063858 32-bitKB3063858 64-bit主题清理好了各个补丁的关系之后咱回到主题。为什么在 dotnet core 一系都有此要求而且还不是对所有 Win7 系统都有此要求这是为什么回答这两个问题可以从 dotnet core 的 dotnet host core run 开始聊起在 Windows 下咱双击运行的 dotnet core 的可执行 exe 文件其实是一个 AppHost 文件。咱编写的 Main 函数在非单文件模式下是放在同名的 dll 里面。详细关于 AppHost 请参阅 dotnet core 应用是如何跑起来的 通过AppHost理解运行过程在 dotnet host core run 里对应代码是 src\coreclr\hosts\corerun\corerun.hpp 文件在这里需要拉起 hostpolicy.dll 组件。加载此组件的代码如下不过代码内容不重要哈inline bool try_load_hostpolicy(pal::string_t mock_hostpolicy_value){const char_t* hostpolicyName W(hostpolicy.dll);pal::mod_t hMod (pal::mod_t)::GetModuleHandleW(hostpolicyName);if (hMod ! nullptr)return true;// Check if a hostpolicy exists and if it does, load it.if (pal::does_file_exist(mock_hostpolicy_value))hMod (pal::mod_t)::LoadLibraryExW(mock_hostpolicy_value.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);if (hMod nullptr)pal::fprintf(stderr, W(Failed to load mock hostpolicy at path %s. Error: 0x%08x\n), mock_hostpolicy_value.c_str(), ::GetLastError());return hMod ! nullptr;}以上最关键的只有这一行代码 LoadLibraryExW(mock_hostpolicy_value.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)以上代码通过 LoadLibraryExW 函数进行加载库。调用时传入了 LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 参数。根据官方文档的描述调用此函数如果加入了 LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 参数将要求 KB2533623 补丁If this value is used, the directory that contains the DLL is temporarily added to the beginning of the list of directories that are searched for the DLL’s dependencies. Directories in the standard search path are not searched. The lpFileName parameter must specify a fully qualified path. This value cannot be combined with LOAD_WITH_ALTERED_SEARCH_PATH. For example, if Lib2.dll is a dependency of C:\Dir1\Lib1.dll, loading Lib1.dll with this value causes the system to search for Lib2.dll only in C:\Dir1. To search for Lib2.dll in C:\Dir1 and all of the directories in the DLL search path, combine this value with LOAD_LIBRARY_DEFAULT_DIRS.Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: This value requires KB2533623 to be installed. Windows Server 2003 and Windows XP: This value is not supported除以上逻辑之外在 dotnet 仓库里还可以找到其他的各个部分的 LoadLibraryExW 函数上也都带上了 LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 参数列表如下src\coreclr\dlls\dbgshim\dbgshim.cpp: CreateDebuggingInterfaceFromVersion2 函数src\coreclr\hosts\corerun\corerun.hpp: try_load_hostpolicy 函数src\coreclr\hosts\coreshim\CoreShim.cpp: TryLoadHostPolicy 函数src\coreclr\vm\nativelibrary.cpp: DetermineLibNameVariations 函数src\native\corehost\hostmisc\pal.windows.cpp: load_library 函数看起来文件不多就看哪个伙伴想不开就去改改挖坑吧此 LoadLibraryExW 函数是放在 Kernel32.dll 的相同的需求在 dotnet core 里也间接依赖于 AddDllDirectory 和 SetDefaultDllDirectories 和 RemoveDllDirectory 等方法。如官方文档描述刚好这些方法也都相同依赖 KB2533623 补丁Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: To use this function in an application, call GetProcAddress to retrieve the function’s address from Kernel32.dll. KB2533623 must be installed on the target platform.通过如上描述可以了解到在 dotnet core 需要补丁的原因是调用了 Kernel32.dll 的新大约10年前加的函数对于一些 Win7 旧设备上没有更新 Kernel32.dll 加上函数因此判断 dotnet core 所依赖环境可以有两个方法第一个方法是判断 KB2533623 补丁是否有安装另一个方法是判断 Kernel32.dll 里是否存在 AddDllDirectory 函数。第一个方法判断是不靠谱的因为不一定需要 KB2533623 补丁如上文描述换成其他几个补丁也可以。判断补丁安装可以使用下面命令行代码更多请参阅 dotnet 通过 WMI 获取系统补丁 和 PowerShell 通过 WMI 获取补丁BAT:wmic qfe GET hotfixid | findstr /C:KB2533623另外判断是否存在 KB2533623 补丁不存在则安装的 bat 脚本代码如下echo off
cd /d %~dp0
wmic qfe GET hotfixid | findstr /C:KB2533623
if %errorlevel% equ 0 (Echo Patch KB2533623 installed) else (
wusa Windows6.1-KB2533623-x64.msu /quiet /norestart
wusa Windows6.1-KB2533623-x86.msu /quiet /norestart
exit /b 1
)
exit /b 0第二个方法我比较推荐判断代码如下using PInvoke;
using System;namespace AddDllDirectoryDetectCs
{class Program{static void Main(string[] args){using (var hModule Kernel32.LoadLibrary(Kernel32.dll)){if (!hModule.IsInvalid){IntPtr hFarProc Kernel32.GetProcAddress(hModule, AddDllDirectory);if (hFarProc ! IntPtr.Zero){Console.WriteLine(Either running on Win8, or KB2533623 is installed);}else{Console.Write(Likely running on Win7 or older OS, and KB2533623 is not installed);}}}// 以下是判断 Universal C Runtime 的逻辑可以忽略using (var hModule Kernel32.LoadLibraryEx(UCRTBASE.dll, IntPtr.Zero, Kernel32.LoadLibraryExFlags.LOAD_LIBRARY_SEARCH_SYSTEM32)){if (!hModule.IsInvalid){Console.WriteLine(UCRT is available - Either running on Win10 or KB2999226 is installed);}else{Console.WriteLine(UCRT is not available - Likely running on OS older than Win10 and KB2999226 is not installed);}}}}
}以上代码由 WPF 框架官方开发 Vatsan Madhavan 大佬提供请看 vatsan-madhavan/checknetcoreprereqs: Helper utility to check .NET Core Prerequisites on Windows systems收到 Vatsan Madhavan 大佬赞参考LoadLibraryExW function (libloaderapi.h) - Win32 apps Microsoft DocsLoadLibraryExA function (libloaderapi.h) - Win32 apps Microsoft DocsLoadLibraryW function (libloaderapi.h) - Win32 apps Microsoft Docswindows - SetDllDirectory does not cascade, so dependency DLLs cannot be loaded - Stack OverflowSetDllDirectoryA function (winbase.h) - Win32 apps Microsoft DocsAddDllDirectory function (libloaderapi.h) - Win32 apps Microsoft DocsWindows installer should warn about missing required updated · Issue #2452 · dotnet/runtimeRemoveDllDirectory function (libloaderapi.h) - Win32 appsUnable to load DLL ‘wpfgfx_cor3.dll’ or one of its dependencies · Issue #2009 · dotnet/wpfSqlClient: Unable to load DLL ‘sni.dll’ · Issue #16905 · dotnet/runtimeFailed to bind to coreclr dotnet run failure on Windows 7 and Windows 2008 R2 · Issue #5590 · dotnet/sdkAPI Set Usage Question · Issue #5075 · dotnet/runtimeCannot load CoreCLR.dll · Issue #5076 · dotnet/runtimevatsan-madhavan/checknetcoreprereqs: Helper utility to check .NET Core Prerequisites on Windows systems使用 C# 判断指定的 Windows 更新是否已安装-码农很忙Windows 7 安装 msu 系统更新时的常见报错及解决办法-码农很忙Windows 7 安装 .NET 5 / .NET Core 3.1 环境的方法和依赖文件-码农很忙Windows 7 SP 1 部署 .NET 6 Desktop Runtime 桌面运行时会遇到的问题-码农很忙