有没有办法从 C# WPF 应用程序中刷新 DNS 缓存? (在 XP、Vista、Win7 上)
Posted
技术标签:
【中文标题】有没有办法从 C# WPF 应用程序中刷新 DNS 缓存? (在 XP、Vista、Win7 上)【英文标题】:Is there a way to flush the DNS cache from a C# WPF app? (on XP, Vista, Win7) 【发布时间】:2011-03-30 17:25:27 【问题描述】:有没有办法从 C# WPF 应用程序中刷新 DNS 缓存?该应用程序可以在 XP、Vista 或 Windows 7 上运行。
【问题讨论】:
brannickdevice.blogspot.com/2006/04/… @Aaron:很遗憾你没有发布答案。我会投票赞成。 @kbrimington,对于我在 google 中找到的第一个结果(微笑)发布答案,我感觉不对:tinyurl.com/2bx8ngu @Aaron:很公平。你真好。 3 年后,这是第一个结果。那篇文章是第 7 篇;)。 【参考方案1】:您可以使用 Microsoft 的“dnsapi.dll”中的函数。这将允许您完全以编程方式执行此操作:
using System.Runtime.InteropServices;
[DllImport("dnsapi.dll",EntryPoint="DnsFlushResolverCache")]
private static extern UInt32 DnsFlushResolverCache ();
public static void FlushMyCache() //This can be named whatever name you want and is the function you will call
UInt32 result = DnsFlushResolverCache();
我已经对此进行了测试,效果很好。
【讨论】:
我运行代码并且它正在工作,但我如何知道该进程是否已成功清除 DNS 缓存?DnsFlushResolverCache()
是一个未记录的函数,这意味着它的未来无法保证。
这可能曾经可以工作,但在 Win10 中尝试此操作目前会产生 Incorrect Function 错误。它也不再列在 msdn 文档中,也不是我在 NuGet 中看到的 PInvoke 库的一部分。【参考方案2】:
这可能是穷人的解决方案,但您可以使用System.Diagnostics.Process
启动ipconfig /flushdns
。
【讨论】:
还好,挖掘pinvoke似乎是浪费精力。 不错的后备方案 - 可能会等着看其他人是否知道隐藏在 .net 框架中的东西 - 如果在任何地方,你会认为它会在 DNS 类中,但我没有看到什么都有 只要不考虑移植到其他平台,就可以使用这个。 感觉这不是理想的解决方案,但 dnsapi.dll PInvoke 函数似乎不再存在。【参考方案3】:我在互联网上搜索并找不到刷新单个 dns 条目。我需要做一些故障转移到备份数据中心的工作。我拆解了 DnsFlushResolverCacheEntry_W 并提出了下面的 p/invoke sig。我使用带有 QueryNoWireFlag 和 NoHostFile 标志的 DnsQuery 方法。如果有任何结果,我会打电话 DnsFlushResolverCacheEntry_W。对于将来希望做同样事情的人来说,这可能是个好信息
/// <summary>
/// Removes all related DNS records for the given hostname from the DNS resolver cache.
/// </summary>
/// <param name="hostName">The host name to flush from the resolver cache.</param>
/// <returns>Returns 1 if successful, zero if failed. No other error information is returned.</returns>
/// <remarks>
/// DnsFlushResolverCacheEntry_W is an undocumented method. From dissembler this method has two possible
/// return values 0 or 1. If the argument is null or the _R_ResolverFlushCacheEntry returns something
/// other than zero than the return value is zero. When _R_ResolverFlushCacheEntry returns zero the
/// return value is 1. Based off this and testing of the method it is assumed that 1 is used to indicate success.
/// After calling this method querying the DNS resolver cache returns no results.
///
/// __stdcall DnsFlushResolverCacheEntry_W(x)
/// ....
/// 6DC12729 xor esi, esi // Zero esi
/// 6DC1272B cmp [ebp+arg_0], esi // check if the hostname is null
/// 6DC1272E jz loc_6DC1D8B8 // Jump to end, return value is 0.
/// 6DC12734 mov [ebp+ms_exc.registration.TryLevel], esi
/// 6DC12737 push esi // Push 3 args for method, 2nd is hostname, others null
/// 6DC12738 push [ebp+arg_0]
/// 6DC1273B push esi
/// 6DC1273C call _R_ResolverFlushCacheEntry@12 // call this method
/// 6DC12741 mov [ebp+var_1C], eax // store return value in local
/// 6DC12744 mov [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
/// 6DC1274B
/// 6DC1274B loc_6DC1274B:
/// 6DC1274B cmp [ebp+var_1C], esi
/// 6DC1274E jnz loc_6DC1D8E7 // Error? jump to block that does etw then return 0
/// 6DC12754 xor eax, eax // Success? Set eax to zero
/// 6DC12756 inc eax // result is 0, increment by 1. success return value is 1
/// 6DC12757 call __SEH_epilog4
/// 6DC1275C retn 4
///
/// 6DC1D8B8 xor eax, eax // set return value to zero
/// 6DC1D8BA jmp loc_6DC12757 // jump to end
///
/// 6DC1D8E7 mov eax, _WPP_GLOBAL_Control
/// 6DC1D8EC cmp eax, offset _WPP_GLOBAL_Control
/// 6DC1D8F1 jz short loc_6DC1D8B8
/// 6DC1D8F3 test byte ptr [eax+1Ch], 40h
/// 6DC1D8F7 jz short loc_6DC1D8B8 // This is probably testing some flag that is used to indicate if ETW is enabled
/// 6DC1D8F9 push [ebp+var_1C]
/// 6DC1D8FC push offset dword_6DC22494
/// 6DC1D901 push 0Dh
/// 6DC1D903 push dword ptr [eax+14h]
/// 6DC1D906 push dword ptr [eax+10h]
/// 6DC1D909 call _WPP_SF_q@20 ; WPP_SF_q(x,x,x,x,x) // This method does some ETW tracing
/// 6DC1D90E jmp short loc_6DC1D8B8
/// </remarks>
[DllImport("dnsapi.dll", EntryPoint = "DnsFlushResolverCacheEntry_W", CharSet = CharSet.Unicode)]
public static extern int DnsFlushResolverCacheEntry(string hostName);
【讨论】:
【参考方案4】:试试这个 -
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C ipconfig /flushdns";
process.StartInfo = startInfo;
process.Start();
【讨论】:
通过运行终端进程来执行此操作似乎有点 hacky。我希望原始海报更喜欢另一种方式。 为什么不直接启动ipconfig /flushdns
?【参考方案5】:
试试这个:
static void flushDNS()
string flushDnsCmd = @"/C ipconfig /flushdns";
try
var process = new Process
StartInfo = new ProcessStartInfo("cmd.exe", flushDnsCmd)
;
process.Start();
process.WaitForExit();
Console.WriteLine(String.Format("Successfully Flushed DNS:'0'", flushDnsCmd), EventLogEntryType.Information);
catch (Exception exp)
Console.WriteLine(String.Format("Failed to Flush DNS:'0' . Error:1", flushDnsCmd, exp.Message), EventLogEntryType.Error);
【讨论】:
以上是关于有没有办法从 C# WPF 应用程序中刷新 DNS 缓存? (在 XP、Vista、Win7 上)的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在没有 WPF 或 Visual Studio 的情况下在 C# 中制作 GUI(仅使用代码)?
有没有办法使用 Wpf (C#) 更改 Web 浏览器的上下文菜单
有没有办法在不通知 ItemsSource 集合的情况下使用 ObservableCollection 和 MVVM 刷新 WPF DataGrid?