winapi - 如何清除/刷新 Win32 API 中的 DNS 缓存
问题描述
我正在寻找一种以编程方式清除/刷新本地 win32 dns 缓存的方法(相当于调用“ipconfig /flushdns”)。
有一些方法可以使用 winsock.dll 中的隐藏 API 执行此操作,但 winsock.dll 不再是 Windows 的一部分,因此此方法将不再有效。
有谁知道现在应该怎么做?
解决方案
- 使用Dependency Walker检查ipconfig.exe的依赖项
- 在其中找到dnsapi.dll
- 检查其导出的函数,发现DnsFlushResolverCache
- 浅浅浏览了一下网页,找到了它的签名(只在官网找到这样的引用:[MS.Docs]: Windows 8 API Sets),意思是它不是公开的,所以依赖它的软件不健壮)
- 创建了一个小测试程序
main00.c:
#include <stdio.h>
#include <Windows.h>
typedef BOOL (WINAPI *DnsFlushResolverCacheFuncPtr)();
int main() {
HMODULE dnsapi = LoadLibrary("dnsapi.dll");
if (dnsapi == NULL) {
printf("Failed loading module: %d\n", GetLastError());
return -1;
}
DnsFlushResolverCacheFuncPtr DnsFlushResolverCache = (DnsFlushResolverCacheFuncPtr)GetProcAddress(dnsapi, "DnsFlushResolverCache");
if (DnsFlushResolverCache == NULL) {
printf("Failed loading function: %d\n", GetLastError());
FreeLibrary(dnsapi);
return -2;
}
BOOL result = DnsFlushResolverCache();
if (result) {
printf("DnsFlushResolverCache succeeded\n");
} else {
printf("DnsFlushResolverCache succeeded: %d\n", GetLastError());
}
FreeLibrary(dnsapi);
return 0;
}
输出:
e:\Work\Dev\StackOverflow\q052007372>"c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x64 e:\Work\Dev\StackOverflow\q052007372>dir /b dnsapi_func_list.txt main00.c e:\Work\Dev\StackOverflow\q052007372>cl /nologo main00.c /link /OUT:main00.exe main00.c e:\Work\Dev\StackOverflow\q052007372>dir /b dnsapi_func_list.txt main00.c main00.exe main00.obj e:\Work\Dev\StackOverflow\q052007372>main00.exe DnsFlushResolverCache succeeded
注意:即使函数调用成功完成,我也不确定如何检查它是否完成了它应该做的事情(或者更好:它的名字暗示它应该做什么,这似乎是你需要的)。
让我知道它是如何工作的。
更新#0
感谢您提供@TimJohnson 的信息!!我也急于查看ipconfig /?
([MS.Docs]: ipconfig)输出(我在另一个cmd窗口 :d 中)并注意选项:) 。
它确实有效(缓存被大量更新,我可以看到运行程序前后的差异)!!!
推荐阅读
- c# - Angular 6 和 .Net Core 2 - 生成 XSRF 令牌,但在发送回 API 时为空
- python - 如何调试此脚本,以便将数字替换为 python 中存在 % 的位置?
- react-native - 如何在 Expo 中使用 DocumentPicker 选择多个文件?
- python - Tkinter 文本小部件搜索方法
- ios - How to check two optional UITextFields
- javascript - 如何替换 addRange() 以在 Google Chrome 中进行多项选择?
- django-rest-framework - AttributeError:Serializer DateField 将值转换为字节
- git - 如何通过 Docker 机密共享 SSH 密钥以访问私有 Github 存储库?
- google-signin - 三星 Galaxy s7 id_token 缺少名称声明
- vue.js - Veevalidate:在 POST 请求之前验证表单?