C#调用阿里云接口实现动态域名解析,支持IPv6(Windows系统下载可用)

电信宽带一般能申请到公网IP,但是是动态的,基本上每天都要变,所以想到做一个定时任务,随系统启动,网上看了不少博文很多都支持IPv4,自己动手写了一个。

(私信可全程指导)

部署步骤:

1、下载软件包,修改配置文件

下载地址:私信获取

下载压缩包,解压后修改配置文件AliDDNS.exe.config中的阿里云帐号和自己的域名。

2、修改脚本,并运行脚本

将“安装服务.bat”和“卸载服务.bat”脚本中的可执行文件路径,改为自己的软件包所在路径,然后右键“安装服务.bat”进行安装服务。

执行脚本后会将定时服务添加到系统服务中。

3、启动服务

右键“此电脑”,点击“管理”进入计算机管理窗口,在服务列表中找到上一步新增的服务,然后启动。即可定时更新阿里云解析记录,实现动态IP的DDNS。

源代码:


/// <summary>
/// 刷新阿里云域名解析记录
/// </summary>
private void RefreshAliRecord()
{
    string recordTypes = ConfigurationManager.AppSettings["RecordTypes"];
    if (string.IsNullOrWhiteSpace(recordTypes))
    {
        NLogHelper.WriteLog(typeof(AliDDNS), "配置文件中的“待解析的协议类型”不能为空。", NLogLevel.Warn);
        return;
    }

    string regionId = ConfigurationManager.AppSettings["RegionId"];
    string accessKeyID = ConfigurationManager.AppSettings["AccessKeyID"];
    string accessKeySecret = ConfigurationManager.AppSettings["AccessKeySecret"];
    string domainName = ConfigurationManager.AppSettings["DomainName"];
    string rR = ConfigurationManager.AppSettings["RR"];

    string[] rRTypes = rR.Split('|');

    // regionId:地区节点
    // accessKeyID:阿里云Key
    // accessKeySecret:阿里云密钥
    AlibabaCloudCredentialsProvider provider = new AccessKeyCredentialProvider(accessKeyID, accessKeySecret);
    IClientProfile profile = DefaultProfile.GetProfile(regionId);
    DefaultAcsClient client = new DefaultAcsClient(profile, provider);

    List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> recordList = DescribeDomainRecords(client, domainName);

    string[] recordTypeArray = recordTypes.Split('|');
    foreach (string recordType in recordTypeArray)
    {
        if (recordType == "A")
        {
            #region IPv4解析记录
            try
            {
                string urls = ConfigurationManager.AppSettings["GetIPFromUrl"];
                string ipv4 = CommonHelper.GetExtranetIP(urls.Split('|').ToList());
                if (string.IsNullOrWhiteSpace(ipv4))
                {
                    NLogHelper.WriteLog(typeof(AliDDNS), "未获取到外网IPv4地址!", NLogLevel.Warn);
                    return;
                }

                if (IsAddSuccessLog)
                {
                    NLogHelper.WriteLog(typeof(AliDDNS), "获取到的外网IPv4地址为:" + ipv4, NLogLevel.Info);
                }

                foreach (string rRItem in rRTypes)
                {
                    if (string.IsNullOrWhiteSpace(rRItem))
                    {
                        continue;
                    }

                    List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> ipv4Records = recordList.Where(r => r.Type == recordType && r.RR == rRItem).ToList();
                    if (ipv4Records == null || ipv4Records.Count() == 0)
                    {
                        AddDNSRecord(client, domainName, rRItem, recordType, ipv4);
                    }
                    else
                    {
                        #region 更新解析记录

                        // 非ipv4记录
                        List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> otherRecords = ipv4Records.Where(r => r._Value != ipv4).ToList();
                        // ipv4记录
                        List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> tempList = ipv4Records.Where(r => r._Value == ipv4).ToList();
                        if (tempList == null || tempList.Count == 0)
                        {
                            // 如果不存在该IPv4的记录,则删除所有记录ipv4Records,并新增记录
                            AddDNSRecord(client, domainName, rRItem, recordType, ipv4);

                            DeleteDNSRecord(client, ipv4Records);
                        }
                        else if (tempList.Count == 1)  // 如果只存在一条该IPv4记录,则记录日志,如果有其他记录则删除
                        {
                            NLogHelper.WriteLog(typeof(AliDDNS), string.Format("同类型(“{0}”类型)的解析记录(IPv4:{1})已存在,无需更新!", rRItem, ipv4), NLogLevel.Info);
                            if (ipv4Records.Count != tempList.Count)
                            {
                                // 存在其他记录,则删除其他记录otherRecords
                                DeleteDNSRecord(client, otherRecords);
                            }
                        }
                        else
                        {
                            // 如果存在多条该IPv4记录,则取第一条,其他的记录都删除
                            tempList.RemoveRange(0, 1);
                            otherRecords.AddRange(tempList);
                            DeleteDNSRecord(client, otherRecords);
                        }
                        #endregion
                    }
                }
            }
            catch (Exception ex)
            {
                NLogHelper.WriteLog(typeof(AliDDNS), "查询并更新IPv4解析记录时异常:" + ex.ToString(), NLogLevel.Warn);
            }

            #endregion
        }
        else if (recordType == "AAAA")
        {
            #region IPv6解析记录
            try
            {
                List<string> ipv6List = CommonHelper.GetLocalIPv6();
                if (ipv6List == null || ipv6List.Count() == 0)
                {
                    NLogHelper.WriteLog(typeof(AliDDNS), "未获取到本机IPv6地址!", NLogLevel.Warn);
                    return;
                }

                if (IsAddSuccessLog)
                {
                    NLogHelper.WriteLog(typeof(AliDDNS), "获取到的本地IPv6地址为:" + string.Join(",", ipv6List), NLogLevel.Info);
                }

                string defaultIPv6 = ipv6List[0];  // 默认只添加第一个IPv6地址

                foreach (string rRItem in rRTypes)
                {
                    if (string.IsNullOrWhiteSpace(rRItem))
                    {
                        continue;
                    }

                    List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> ipv6Records = recordList.Where(r => r.Type == recordType && r.RR == rRItem).ToList();
                    if (ipv6Records == null || ipv6Records.Count() == 0)
                    {
                        AddDNSRecord(client, domainName, rRItem, recordType, defaultIPv6);
                    }
                    else
                    {
                        #region 更新解析记录

                        // 非ipv6记录
                        List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> otherRecords = ipv6Records.Where(r => r._Value != defaultIPv6).ToList();
                        // ipv6记录
                        List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> tempList = ipv6Records.Where(r => r._Value == defaultIPv6).ToList();
                        if (tempList == null || tempList.Count == 0)
                        {
                            // 如果不存在该IPv6的记录,则删除所有记录ipv6Records,并新增记录
                            AddDNSRecord(client, domainName, rRItem, recordType, defaultIPv6);

                            DeleteDNSRecord(client, ipv6Records);
                        }
                        else if (tempList.Count == 1)  // 如果只存在一条该IPv6记录,则记录日志,如果有其他记录则删除
                        {
                            NLogHelper.WriteLog(typeof(AliDDNS), string.Format("同类型(“{0}”类型)的解析记录(IPv6:{1})已存在,无需更新!", rRItem, defaultIPv6), NLogLevel.Info);
                            if (ipv6Records.Count != tempList.Count)
                            {
                                // 存在其他记录,则删除其他记录otherRecords
                                DeleteDNSRecord(client, otherRecords);
                            }
                        }
                        else
                        {
                            // 如果存在多条该IPv6记录,则取第一条,其他的记录都删除
                            tempList.RemoveRange(0, 1);
                            otherRecords.AddRange(tempList);
                            DeleteDNSRecord(client, otherRecords);
                        }

                        #endregion
                    }
                }
            }
            catch (Exception ex)
            {
                NLogHelper.WriteLog(typeof(AliDDNS), "查询并更新IPv6解析记录时异常:" + ex.ToString(), NLogLevel.Warn);
            }
            #endregion
        }
    }
}

// 获取指定主域名的所有解析记录列表
public List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> DescribeDomainRecords(DefaultAcsClient client, string domainName)
{
    List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> records = new List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record>();
    try
    {
        DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
        request.DomainName = domainName;

        记录类型 官网支持A/CNAME/MX/AAA/TXT/NS/SRV/CAA/URL隐性(显性)转发如果有需要可将该值配置为参数传入
        //request.Type = recordType;

        try
        {
            DescribeDomainRecordsResponse response = client.GetAcsResponse(request);
            if (IsAddSuccessLog)
            {
                NLogHelper.WriteLog(typeof(AliDDNS), "查询到的解析记录:" + System.Text.Encoding.Default.GetString(response.HttpResponse.Content), NLogLevel.Info);
            }

            if (response.DomainRecords != null)
            {
                records = response.DomainRecords;
            }
        }
        catch (Exception ex)
        {
            NLogHelper.WriteLog(typeof(AliDDNS), "调用DescribeDomainRecords接口时发生异常:" + ex.ToString(), NLogLevel.Error);
        }
    }
    catch (Exception ex)
    {
        NLogHelper.WriteLog(typeof(AliDDNS), "创建DescribeDomainRecords接口调用对象时发生异常:" + ex.ToString(), NLogLevel.Error);
    }
    return records;
}

// 新增解析记录
public void AddDNSRecord(DefaultAcsClient client, string domainName, string rRItem, string recordType, string ipValue)
{
    #region 新增解析记录

    string recordStr = string.Format("(RR:{0},Type:{1},Value:{2})", rRItem, recordType, ipValue);
    try
    {
        var request = new AddDomainRecordRequest();
        request.DomainName = domainName;
        request.RR = rRItem;
        request.Type = recordType;
        request._Value = ipValue;
        request.TTL = 600;  // 免费版,默认600秒,10分钟

        var response = client.GetAcsResponse(request);
        if (IsAddSuccessLog)
        {
            NLogHelper.WriteLog(typeof(AliDDNS), string.Format("新增解析记录{0}时接口返回内容:{1}", recordStr, Encoding.Default.GetString(response.HttpResponse.Content)), NLogLevel.Info);
        }
    }
    catch (Exception ex)
    {
        NLogHelper.WriteLog(typeof(AliDDNS), string.Format("新增解析记录{0}时发生异常:{1}", recordStr, ex.ToString()), NLogLevel.Error);
    }
    #endregion
}

// 删除解析记录
public void DeleteDNSRecord(DefaultAcsClient client, List<DescribeDomainRecordsResponse.DescribeDomainRecords_Record> deleteList)
{
    #region 删除解析记录

    foreach (DescribeDomainRecordsResponse.DescribeDomainRecords_Record record in deleteList)
    {
        string recordStr = string.Format("(RR:{0},Type:{1},Value:{2})", record.RR, record.Type, record._Value);
        try
        {
            DeleteDomainRecordRequest request = new DeleteDomainRecordRequest();
            request.RecordId = record.RecordId;

            DeleteDomainRecordResponse response = client.GetAcsResponse(request);
            if (IsAddSuccessLog)
            {
                NLogHelper.WriteLog(typeof(AliDDNS), string.Format("删除解析记录{0}时接口返回内容:{1}", recordStr, Encoding.Default.GetString(response.HttpResponse.Content)), NLogLevel.Info);
            }
        }
        catch (Exception ex)
        {
            NLogHelper.WriteLog(typeof(AliDDNS), string.Format("删除解析记录{0}时发生异常:{1}", recordStr, ex.ToString()), NLogLevel.Error);
        }
    }

    #endregion
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/256412.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

20231218在Ubuntu18.04下以EXT4格式化HDD

20231218在Ubuntu18.04下以EXT4格式化HDD 2023/12/18 17:24 缘起&#xff1a; 编译一个Android10大概要200GB&#xff0c;编译10个Android10的SDK&#xff0c;3TB的HDD机械硬盘就估计会被填满了&#xff01; 如果使用rm -rf *这个命令将SDK一个一个逐个地删除&#xff0c;估计2…

强大的电子书阅读器:OmniReader Pro for mac

&#x1f50d; OmniReader Pro 是一款专为 Mac 设计的强大阅读工具&#xff0c;它能够帮助你更高效地阅读和处理各种文本内容。无论是电子书、新闻文章、网页文本还是文件资料&#xff0c;OmniReader Pro 都能胜任&#xff01; ✅ OmniReader Pro 提供了丰富的功能&#xff0c…

UE5 C++(六)— 枚举UENUM、结构体USTRUCT和补充属性说明符

文章目录 枚举&#xff08;ENUM&#xff09;第一种方式第二种方式 结构体&#xff08;USTRUCT&#xff09;补充属性说明符&#xff08;ExposeOnSoawn&#xff09;结构体创建数据表格 枚举&#xff08;ENUM&#xff09; 第一种方式 定义枚举 UENUM(BlueprintType) namespace …

java配置+J_IDEA配置+git配置+maven配置+基本语句

当前目录文件夹dir 进入文件夹cd 返回上一级cd.. 创建文件夹&#xff1a;mkdir 文件名删除文件夹&#xff1a;rd 文件夹名&#xff0c; 目录不为空不能直接删 rd /s 带子文件夹一起删 清屏cls 切换d盘才能进入 下载git地址&#xff1a; Git - Downloading Package (g…

Linux网络编程(一):网络基础(上)

参考引用 UNIX 环境高级编程 (第3版)嵌入式Linux C应用编程-正点原子 1. 网络通信概述 网络通信本质上是一种进程间通信&#xff0c;是位于网络中不同主机上的进程之间的通信&#xff0c;属于 IPC 的一种&#xff0c;通常称为 socket IPC&#xff0c;网络通信是为了解决在网络…

德思特EMC RICI测试方案助您对抗电磁设备干扰!

来源&#xff1a;德思特测试测量 德思特方案丨德思特EMC RICI测试方案助您对抗电磁设备干扰&#xff01; 原文链接&#xff1a;https://mp.weixin.qq.com/s/D8wdQr_reaFG-yppT8nzkw 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; 方案背景 电磁或射频干扰的敏感性&…

【AIGC重塑教育】AI大模型驱动的教育变革与实践

文章目录 &#x1f354;现状&#x1f6f8;解决方法✨为什么要使用ai&#x1f386;彩蛋 &#x1f354;现状 AI正迅猛地改变着我们的生活。根据高盛发布的一份报告&#xff0c;AI有可能取代3亿个全职工作岗位&#xff0c;影响全球18%的工作岗位。在欧美&#xff0c;或许四分之一…

(八)STM32 USART —— 串口通讯

目录 1. 串口通讯协议简介 1.1 物理层 1.1.1 电平标准 1&#xff09;TTL 电平 2&#xff09;RS-232 电平 3&#xff09;RS-485 电平 4&#xff09;CAN 总线电平 1.1.2 USB 和 串口 的区分 1.1.3 RS-232 信号线 1.2 协议层 1&#xff09;波特率 2&#xff09;通讯…

Arcgis中利用模型构建器统一栅格数据的行列号

1、统一&#xff08;X,Y) 方法&#xff1a;"数据管理工具箱"→"Projections and Transformations"→"Raster"→"Project Raster" 构建模型 这里以行列号最小的栅格&#xff08;X,Y&#xff09;为准&#xff08;其实也就是栅格数据的空…

数据可视化---离群值展示

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

全球通关第一人,分享阿里云新版ACE认证备考攻略~

2022.3月底阿里云针对老版ACE进行了改版&#xff0c;针对云计算技术的发展趋势&#xff0c;新增了云原生等热门技术&#xff0c;同时新版ACE认证新增了实验和面试&#xff0c;全面考查考生的动手能力和理论知识结构&#xff0c;含金量大大提升。 作为阿里云新版ACE全球通关第一…

【智慧之窗】AI驱动产品探索

一.初识 ChatGPT ChatGPT 是由 OpenAI 开发的自然语言处理&#xff08;NLP&#xff09;模型&#xff0c;基于 GPT&#xff08;Generative Pre-trained Transformer&#xff09;架构。GPT 系列的模型旨在理解和生成自然语言文本。ChatGPT 专注于支持对话性任务&#xff0c;即与…

【remb】twcc 与remb的切换测试

500000bps 70kBps 1 000 000 bps后&#xff0c;图像清晰些了&#xff0c;但在mesh下还是会牺牲了它的及时性&#xff1b;上面的几种情况的延时性很大啊&#xff0c;有流畅度&#xff0c;但延时太大 在twcc策略下&#xff0c;我们看到 220kBps时即大概1.6M时&#xff0c;视频才…

【Spring】09 BeanClassLoaderAware 接口

文章目录 1. 简介2. 作用3. 使用3.1 创建并实现接口3.2 配置 Bean 信息3.3 创建启动类3.4 启动 4. 应用场景总结 Spring 框架为开发者提供了丰富的扩展点&#xff0c;其中之一就是 Bean 生命周期中的回调接口。本文将聚焦于其中的一个接口 BeanClassLoaderAware&#xff0c;介…

Day65力扣打卡

打卡记录 寻找峰值 II&#xff08;二分&#xff09; 链接 class Solution:def findPeakGrid(self, mat: List[List[int]]) -> List[int]:l, r 0, len(mat) - 1while l < r:mid (l r) // 2mx max(mat[mid])if mx > mat[mid 1][mat[mid].index(mx)]:r midelse:l…

外包干了6个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

xcrun: error: invalid active developer path

macOS升级完成后出现 xcrun: error: invalid active developer path问题。 xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun这是由于 Xcode command line tools 丢…

Web开发:如何在Visual Studio2022中使用Codeium(AI)编写代码

一、安装 【此款AI】免费&#xff01;免费&#xff01;免费&#xff01;使用时正常上网即可&#xff01; 1.前提条件 VS2022版本在17.5.5版本以上&#xff08;若版本不够则需要先更新&#xff09;安装和注册需要科学上网&#xff0c;使用则正常上网即可 2.开始下载扩展 方法…

springboot学习笔记(二)

1.Spring 和SpringBoot区别 2.Web开发入门 3.MVC模型 4.RequestMapping用法 5.RESTful 1.Spring 和SpringBoot区别 参考&#xff1a; 大家都懂Spring和SpringBoot的区别吗&#xff1f; - 知乎 https://www.zhihu.com/question/598494506/answer/3018702101 在学习了Spri…

现代化智慧档案馆八防十防建设调研样本

以下是一份完整的解决方案&#xff0c;包括方案介绍、方案优势、实施方案、预算和清单、实施时间和进度计划以及可能遇到的难点和解决方案。 方案介绍 档案库房八防十防环境一体化监控系统旨在为档案库房提供全方位的环境监控和管理&#xff0c;保障档案的安全、稳定和可靠。该…