├── DNSPod.Service.sln
├── DNSPod.Service
├── App.config
├── DNSPod.Service.csproj
├── DNSPod.Service.csproj.user
├── DNSPodService.Designer.cs
├── DNSPodService.cs
├── Program.cs
├── ProjectInstaller.Designer.cs
├── ProjectInstaller.cs
├── ProjectInstaller.resx
├── Properties
│ └── AssemblyInfo.cs
├── Utils
│ ├── Helpter.cs
│ ├── LogCategory.cs
│ ├── LoginInfo.cs
│ └── Record.cs
├── conf
│ └── conf.xml
└── packages.config
└── README.md
/DNSPod.Service.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26430.14
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DNSPod.Service", "DNSPod.Service\DNSPod.Service.csproj", "{965EA5A0-65F9-4875-B01F-D949DB92DF8D}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|ARM = Debug|ARM
12 | Debug|ARM64 = Debug|ARM64
13 | Debug|x64 = Debug|x64
14 | Debug|x86 = Debug|x86
15 | Release|Any CPU = Release|Any CPU
16 | Release|ARM = Release|ARM
17 | Release|ARM64 = Release|ARM64
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|ARM.ActiveCfg = Debug|Any CPU
25 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|ARM.Build.0 = Debug|Any CPU
26 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
27 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|ARM64.Build.0 = Debug|Any CPU
28 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|x64.ActiveCfg = Debug|Any CPU
29 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|x64.Build.0 = Debug|Any CPU
30 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|x86.ActiveCfg = Debug|Any CPU
31 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Debug|x86.Build.0 = Debug|Any CPU
32 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|ARM.ActiveCfg = Release|Any CPU
35 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|ARM.Build.0 = Release|Any CPU
36 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|ARM64.ActiveCfg = Release|Any CPU
37 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|ARM64.Build.0 = Release|Any CPU
38 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|x64.ActiveCfg = Release|Any CPU
39 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|x64.Build.0 = Release|Any CPU
40 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|x86.ActiveCfg = Release|Any CPU
41 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}.Release|x86.Build.0 = Release|Any CPU
42 | EndGlobalSection
43 | GlobalSection(SolutionProperties) = preSolution
44 | HideSolutionNode = FALSE
45 | EndGlobalSection
46 | GlobalSection(ExtensibilityGlobals) = postSolution
47 | SolutionGuid = {1AEE6EAA-80A9-4338-8614-1AC889A66577}
48 | EndGlobalSection
49 | EndGlobal
50 |
--------------------------------------------------------------------------------
/DNSPod.Service/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/DNSPod.Service/DNSPod.Service.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {965EA5A0-65F9-4875-B01F-D949DB92DF8D}
8 | Exe
9 | DNSPod.Service
10 | DNSPod.Service
11 | v4.5
12 | 512
13 | true
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 | false
36 |
37 |
38 | true
39 |
40 |
41 |
42 |
43 |
44 |
45 | ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | Component
62 |
63 |
64 | DNSPodService.cs
65 |
66 |
67 | Component
68 |
69 |
70 | ProjectInstaller.cs
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | Always
86 | Designer
87 |
88 |
89 |
90 |
91 | ProjectInstaller.cs
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/DNSPod.Service/DNSPod.Service.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ShowAllFiles
5 |
6 |
--------------------------------------------------------------------------------
/DNSPod.Service/DNSPodService.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace DNSPod.Service
2 | {
3 | partial class DNSPodService
4 | {
5 | ///
6 | /// 必需的设计器变量。
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// 清理所有正在使用的资源。
12 | ///
13 | /// 如果应释放托管资源,为 true;否则为 false。
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region 组件设计器生成的代码
24 |
25 | ///
26 | /// 设计器支持所需的方法 - 不要修改
27 | /// 使用代码编辑器修改此方法的内容。
28 | ///
29 | private void InitializeComponent()
30 | {
31 | components = new System.ComponentModel.Container();
32 | this.ServiceName = "Service1";
33 | }
34 |
35 | #endregion
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/DNSPod.Service/DNSPodService.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json.Linq;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Net;
6 | using System.ServiceProcess;
7 | using System.Threading;
8 | using System.Xml;
9 |
10 | namespace DNSPod.Service
11 | {
12 | public partial class DNSPodService : ServiceBase
13 | {
14 | public DNSPodService()
15 | {
16 | InitializeComponent();
17 | }
18 | string currentPath = string.Empty;
19 | string logPath = string.Empty;
20 |
21 | static LoginInfo login = new LoginInfo();
22 | static List listRecord = new List();
23 | static int Time = 0;
24 | static string ip = string.Empty;
25 | protected override void OnStart(string[] args)
26 | {
27 | try
28 | {
29 | InitData();
30 | new Thread(delegate ()
31 | {
32 | while (true)
33 | {
34 | ReferData();
35 | Thread.Sleep(Time);
36 | }
37 | }).Start();
38 | Thread.Sleep(1000);
39 | }
40 | catch (Exception ex)
41 | {
42 | Helpter.WriteLineLog(logPath, LogCategory.Config, ex.Message);
43 | throw;
44 | }
45 | }
46 |
47 | protected override void OnStop()
48 | {
49 | }
50 | void ReferData()
51 | {
52 | try
53 | {
54 | string _ip = Helpter.GetPublicIP();
55 | foreach (Record item in listRecord)
56 | {
57 | item.ip = _ip;
58 | if (item.ip == item._ip)
59 | {
60 | Helpter.WriteLineLog(logPath, LogCategory.Api, $"上次轮训ip[{item._ip}]与本次获取ip:[{item.ip}]一致");
61 | return;
62 | }
63 | var json = Helpter.RecordList(login.login_token, item.domain, item.subdomain);
64 | if (json.status.code != 1)//操作失败,立刻结束操作
65 | {
66 | Helpter.WriteLineLog(logPath, LogCategory.Api, "登陆认证失败,轮询已停止");
67 | this.Stop();
68 | return;
69 | //Thread.CurrentThread.Abort();
70 | }
71 | item._ip = item.ip;
72 | int recordId = 0;
73 | if (json.records != null && json.records.Count > 0)
74 | {
75 | if (json.records[0].value == item.ip)//与记录中的ip一致,不需要操作
76 | {
77 | Helpter.WriteLineLog(logPath, LogCategory.Api, $"[{item.subdomain}.{item.domain}] 记录值 [{item.ip}] 与服务器记录一致不需要修改");
78 | continue;
79 | }
80 | recordId = json.records[0].id;
81 | }
82 | else
83 | recordId = Helpter.RecordCreate(login.login_token, item.domain, item.subdomain, item.ip);
84 | if (recordId > 0)
85 | json = Helpter.RecordDdns(login.login_token, recordId, item.domain, item.subdomain, item.ip);
86 | Helpter.WriteLineLog(logPath, LogCategory.Api, $"[{item.subdomain}.{item.domain}] 记录值 [{item.ip}] 更新成功");
87 | }
88 | }
89 | catch (Exception ex)
90 | {
91 | Helpter.WriteLineLog(logPath, LogCategory.Api, ex.Message);
92 | }
93 | }
94 |
95 | void InitData()
96 | {
97 | try
98 | {
99 | ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
100 | //currentPath = Directory.GetCurrentDirectory() + "\\";
101 | //currentPath=System.Environment.CurrentDirectory;
102 | currentPath = AppDomain.CurrentDomain.BaseDirectory;
103 | logPath = $"{currentPath}logs\\";
104 | string xml = currentPath + "conf\\conf.xml";
105 | Directory.CreateDirectory(logPath);
106 | Helpter.WriteLineLog(logPath, LogCategory.Config, "-------------------------------");
107 | Helpter.WriteLineLog(logPath, LogCategory.Config, currentPath);
108 | if (!File.Exists(xml))
109 | {
110 | Helpter.WriteLineLog(logPath, LogCategory.Config, $"配置文件不存在{xml}");
111 | throw new Exception($"配置文件不存在{xml}");
112 | }
113 |
114 | XmlDocument doc = new XmlDocument();
115 | doc.Load(xml);
116 | var node = doc.SelectSingleNode("DNSPod.Service");
117 |
118 | Time = Convert.ToInt32(node.SelectSingleNode("Time").Attributes["value"].Value);
119 | if (Time < 5)
120 | {
121 | throw new Exception("间隔时间太短,必须大于等于5,建议为10");
122 | }
123 | Time = Time * 60 * 1000;
124 | login.id = node.SelectSingleNode("LoginDNSPod/id").InnerText;
125 | login.token = node.SelectSingleNode("LoginDNSPod/token").InnerText;
126 |
127 | var nodelist = node.SelectNodes("RecordList/Record");
128 |
129 | foreach (XmlNode item in nodelist)
130 | {
131 | listRecord.Add(new Record()
132 | {
133 | subdomain = item.Attributes["sub_domain"].Value,
134 | domain = item.Attributes["domain"].Value,
135 | });
136 | }
137 | }
138 | catch (Exception ex)
139 | {
140 | Helpter.WriteLineLog(logPath, LogCategory.Config, ex.Message);
141 | throw;
142 | }
143 | }
144 |
145 | public void TestStartupAndStop(string[] args)
146 | {
147 | OnStart(args);
148 | Console.ReadLine();
149 | OnStop();
150 | }
151 |
152 |
153 |
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/DNSPod.Service/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.ServiceProcess;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace DNSPod.Service
10 | {
11 | static class Program
12 | {
13 | ///
14 | /// 应用程序的主入口点。
15 | ///
16 | static void Main(string[] args)
17 | {
18 | if (Environment.UserInteractive)
19 | {
20 | bool isRuned;
21 | Mutex mutex = new Mutex(true, @"Global\DNSPod.Service", out isRuned);
22 | if (isRuned)
23 | {
24 | DNSPodService service = new DNSPodService();
25 | service.TestStartupAndStop(args);
26 | }
27 | }
28 | else
29 | {
30 | ServiceBase[] ServicesToRun;
31 | ServicesToRun = new ServiceBase[]
32 | {
33 | new DNSPodService()
34 | };
35 | ServiceBase.Run(ServicesToRun);
36 |
37 | }
38 |
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/DNSPod.Service/ProjectInstaller.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace DNSPod.Service
2 | {
3 | partial class ProjectInstaller
4 | {
5 | ///
6 | /// 必需的设计器变量。
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// 清理所有正在使用的资源。
12 | ///
13 | /// 如果应释放托管资源,为 true;否则为 false。
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region 组件设计器生成的代码
24 |
25 | ///
26 | /// 设计器支持所需的方法 - 不要修改
27 | /// 使用代码编辑器修改此方法的内容。
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
32 | this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
33 | //
34 | // serviceProcessInstaller1
35 | //
36 | this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
37 | this.serviceProcessInstaller1.Password = null;
38 | this.serviceProcessInstaller1.Username = null;
39 | //
40 | // serviceInstaller1
41 | //
42 | this.serviceInstaller1.Description = "DNSPod DNS 记录自动修改";
43 | this.serviceInstaller1.DisplayName = "DNSPod.Service";
44 | this.serviceInstaller1.ServiceName = "DNSPod.Service";
45 | this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
46 | //
47 | // ProjectInstaller
48 | //
49 | this.Installers.AddRange(new System.Configuration.Install.Installer[] {
50 | this.serviceProcessInstaller1,
51 | this.serviceInstaller1});
52 |
53 | }
54 |
55 | #endregion
56 |
57 | private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
58 | private System.ServiceProcess.ServiceInstaller serviceInstaller1;
59 | }
60 | }
--------------------------------------------------------------------------------
/DNSPod.Service/ProjectInstaller.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Configuration.Install;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace DNSPod.Service
10 | {
11 | [RunInstaller(true)]
12 | public partial class ProjectInstaller : System.Configuration.Install.Installer
13 | {
14 | public ProjectInstaller()
15 | {
16 | InitializeComponent();
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/DNSPod.Service/ProjectInstaller.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 208, 17
125 |
126 |
127 | False
128 |
129 |
--------------------------------------------------------------------------------
/DNSPod.Service/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("DNSPod.Service")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("DNSPod.Service")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("965ea5a0-65f9-4875-b01f-d949db92df8d")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
33 | // 方法是按如下所示使用“*”: :
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/DNSPod.Service/Utils/Helpter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Net.Http;
7 | using System.Net.Security;
8 | using System.Security.Cryptography.X509Certificates;
9 | using System.Text;
10 | using System.Text.RegularExpressions;
11 | using System.Threading.Tasks;
12 | using Newtonsoft.Json.Linq;
13 |
14 | namespace DNSPod.Service
15 | {
16 | public class Dnsapi
17 | {
18 | private const string ApiUrl = "https://dnsapi.cn/";
19 |
20 | public const string List = ApiUrl + "Record.List";
21 |
22 | public const string Create = ApiUrl + "Record.Create";
23 |
24 | public const string Ddns = ApiUrl + "Record.Ddns";
25 |
26 | public const string Modify = ApiUrl + "Record.Modify";
27 | }
28 |
29 | public class Helpter
30 | {
31 | public static string GetPublicIP()
32 | {
33 | string url = new Regex(@"