主代码
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
namespace GithubDNS
{
internal class Program
{
static void Main(string[] args)
{
var ips = GetAppSettingsValue("ips");
GetFastIPDomain(ips);
var globalips = GetAppSettingsValue("gips");
GetFastIPDomain(globalips, "github.global.ssl.fastly.net");
}
public static void GetFastIPDomain(string ips, string domain = "github.com")
{
Dictionary<string, long> dic = new Dictionary<string, long>();
foreach (var ip in ips.Split(','))
{
var time = PingIp(ip);
if (time > 0)
{
dic.Add(ip, time);
}
}
if (dic.Count > 0)
{
var result = dic.OrderBy(c => c.Value).First().Key;
UpdateHost(result, domain);
}
}
public static string GetAppSettingsValue(string key)
{
return ConfigurationManager.AppSettings[key] ?? string.Empty;
}
/// <summary>
/// ping ip,测试能否ping通
/// </summary>
/// <param name="strIP">IP地址</param>
/// <returns></returns>
private static long PingIp(string strIP, int timeOut = 1000)
{
long bRet = 0;
try
{
Ping pingSend = new Ping();
PingReply reply = pingSend.Send(strIP, timeOut);
if (reply.Status == IPStatus.Success)
bRet = reply.RoundtripTime;
}
catch (Exception)
{
bRet = 0;
}
return bRet;
}
public static void UpdateHost(string ip, string domain = "github.com")
{
var OSInfo = Environment.OSVersion;
string pathpart = "hosts";
if (OSInfo.Platform == PlatformID.Win32NT)
{
//is windows NT
pathpart = "system32\\drivers\\etc\\hosts";
}
string hostfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), pathpart);
string tales = $"{ip} {domain}";
string[] lines = File.ReadAllLines(hostfile);
if (lines.Any(s => s.Contains(domain)))
{
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].Contains(domain))
lines[i] = tales;
}
File.WriteAllLines(hostfile, lines);
}
else if (!lines.Contains(tales))
{
File.AppendAllLines(hostfile, new String[] { tales });
}
}
[DllImport("Dnsapi.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DnsFlushResolverCache();
public static bool Flush()
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
return false;
}
if (!DnsFlushResolverCache())
{
ExecuteInCmd("ipconfig /flushdns");
return true;
}
return false;
}
/// <summary>
/// 执行内部命令(cmd.exe 中的命令)
/// </summary>
/// <param name="cmdline">命令行</param>
/// <returns>执行结果</returns>
public static string ExecuteInCmd(string cmdline)
{
using (var process = new Process())
{
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.StandardInput.AutoFlush = true;
process.StandardInput.WriteLine(cmdline + "&exit");
//获取cmd窗口的输出信息
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Close();
return output;
}
}
}
}
配置
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
<add key="gips" value="124.11.210.175,128.242.245.180,108.160.163.112,31.13.68.169,108.160.169.174,31.13.96.195,202.53.137.209,103.240.182.55,108.160.169.55,93.179.102.140,108.160.165.173,69.171.229.73,108.160.162.109,162.125.1.8,103.252.115.221,74.86.151.162,108.160.166.9,157.240.10.32,182.50.139.56,185.60.218.50,108.160.167.30,211.104.160.39,199.59.148.202,199.59.149.238,66.220.146.94,198.44.185.131,157.240.15.8,151.101.1.194,104.244.46.211,66.220.147.11,31.13.91.33,108.160.169.186,199.232.45.194,146.75.49.194,157.240.11.40,150.107.3.176,151.101.109.194,108.160.172.204" />
<add key="ips" value="20.205.243.166,52.78.231.108,15.164.81.167,140.82.113.4,52.192.72.89,140.82.112.3,140.82.113.3,13.114.40.48,192.30.255.112,140.82.114.4,140.82.121.3,192.30.255.113" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>