实验室IP和MAC绑定,而且经常来回于各个实验室和宿舍,频繁的地址切换,带来了相当的烦恼。想做这样一个工具是很久以前的想法,可到现在都没有做;没有行动的想法都是空谈,抱着锻炼自己行动力的决心,完成了这个小工具。

一.工具介绍

工具界面展示:

本工具主要功能:

(1)能够找出所有的网卡适配器,并显示适配器的IP、MAC等信息

(2)能够修改IP、DNS、MAC等地址信息

(3)能够通过配置文件增加/删除网卡信息配置方案,并且能够根据方案进行地址切换,配置文件如下图所示:

二.IP、DNS、MAC的显示功能

2.1如何获取IP、DNS、MAC信息

主要利用Iphlpapi库获取网卡信息,Iphlpapi中IP_ADAPTER_INFO包含了IP、MAC信息但并没有包含DNS:

//获取IP地址信息
void CIpChangeDlg::GetIpAddrsInfo()
{/********************************************通过Iphlpapi库获取网卡信息和个数********************************************/PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();ULONG stSize = sizeof(IP_ADAPTER_INFO);int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);    //获得其大小if (ERROR_BUFFER_OVERFLOW == nRel)                      //重新申请所需要的空间{delete pIpAdapterInfo;pIpAdapterInfo = (PIP_ADAPTER_INFO) new BYTE[stSize];nRel=GetAdaptersInfo(pIpAdapterInfo, &stSize); }if (ERROR_SUCCESS == nRel)                              //获取信息成功{m_AdapterInfo.pIpAdapterInfo = pIpAdapterInfo;m_AdapterInfo.iCount = 0;while (pIpAdapterInfo)                          //获取网卡个数{m_AdapterInfo.iCount++;pIpAdapterInfo = pIpAdapterInfo->Next;}}
}

根据IP_ADAPTER_INFO中的Index,获取相应网卡所使用的DNS信息:

//DNS,pIpAdapterInfo为网卡适配器信息结构PIP_ADAPTER_INFOIP_PER_ADAPTER_INFO* pPerAdapt = NULL;ULONG ulLen = 0;int err = GetPerAdapterInfo( pIpAdapterInfo->Index, pPerAdapt, &ulLen);if( err == ERROR_BUFFER_OVERFLOW ) {pPerAdapt = ( IP_PER_ADAPTER_INFO* ) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulLen);err = GetPerAdapterInfo( pIpAdapterInfo->Index, pPerAdapt, &ulLen );if( err == ERROR_SUCCESS ) {IP_ADDR_STRING* pNext = &( pPerAdapt->DnsServerList );if (pNext && strcmp(pNext->IpAddress.String, "") != 0){m_DNSDHCPBUTTON.SetCheck(FALSE);m_PrimaryDnsCtl.EnableWindow(TRUE);m_BackupDnsCtl.EnableWindow(TRUE);m_PrimaryDnsCtl.SetWindowText(pNext->IpAddress.String);if (pNext = pNext->Next)m_BackupDnsCtl.SetWindowText(pNext->IpAddress.String);}             else{m_DNSDHCPBUTTON.SetCheck(TRUE);m_PrimaryDnsCtl.EnableWindow(FALSE);m_BackupDnsCtl.EnableWindow(FALSE);m_PrimaryDnsCtl.SetWindowText("");m_BackupDnsCtl.SetWindowText("");}}HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, pPerAdapt);}   

2.2如何获得网络连接名称?

对一个网络适配器的名称有三种描述:

(1)适配器对应的注册表中的一个注册表项值,称其为AdapterName;这个信息将在修改MAC的时使用;

(2)适配器描述名称,称其为AdapterDestription,比如本人主机的某一个网卡描述为:“Microsoft Virtual WiFi Miniport Adapter”;

(3)连接名称,就是在操作系统的网络连接中看到的连接名,如"本地连接"等;这个信息将在修改IP/DNS的时使用;

本工具采用netsh命令行方式进行IP/DNS的修改,命令行中进行修改的时候要指定连接名称,如"本地连接",但利用Iphlpapi库并不能获取连接名称,通过Mprapi库中的API和IP_ADAPTER_INFO中的Index 得到网卡所对应的连接名称。

void CIpChangeDlg::GetConnectNames()
{/********************************************通过mprapi库获取连接名称*并通过index将网卡信息和连接名称相关联********************************************/HANDLE   hMprConfig;                    //连接信息的句柄DWORD   dwRet=0;                        //返回值PIP_INTERFACE_INFO   plfTable = NULL;   //接口信息表DWORD   dwBufferSize=0;                 //接口信息表空间大小m_AdapterInfo.csConnectName = new char [m_AdapterInfo.iCount] [256];  //申请空间存储连接名dwRet = MprConfigServerConnect(NULL, &hMprConfig);  //获得句柄dwRet = GetInterfaceInfo(NULL, &dwBufferSize);      //获得接口信息表大小if(dwRet == ERROR_INSUFFICIENT_BUFFER)              //获得接口信息{ plfTable = (PIP_INTERFACE_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize); GetInterfaceInfo(plfTable, &dwBufferSize); } TCHAR   szFriendName[256];                   //接口名称DWORD   tchSize = sizeof(TCHAR) * 256; ZeroMemory(&szFriendName, tchSize);  for (UINT i = 0; i < plfTable-> NumAdapters; i++) { IP_ADAPTER_INDEX_MAP   AdaptMap;         //接口信息AdaptMap = plfTable->Adapter[i]; dwRet = MprConfigGetFriendlyName(hMprConfig, AdaptMap.Name,(PWCHAR)szFriendName, tchSize);      //获得连接名称unicode USES_CONVERSION;char* pName = W2A((PWCHAR)szFriendName);                           //转换为ansiInsertConnectName(AdaptMap.Index, pName);                          //根据Index存储名字信息                                         } HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, plfTable);
}

三.IP、DNS修改

第二章节中以及提到,工具采用命令行方式进行修改;

修改IP命令:

netsh interface ip set address "连接名称" dhcp   //dhcp方式
netsh interface ip set address "连接名称" static IP地址 子网掩码 网关   //静态IP方式

修改DNS命令:

netsh interface ip set dnsservers "连接名称" dhcp      //自动获取方式
netsh interface ip set dnsservers "连接名称" static IP地址  //设置主 DNS
netsh interface ip add dnsservers "连接名称"  IP地址      //设置从属 DNS

四.MAC修改

(1)第一步寻找适配器MAC所在的注册表位置

在注册表"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"目录下遍历寻找 与 AdapterName(2.2节中所提AdatpterName)相同的注册表项NetCfgInstanceId,则相应的MAC地址存储在相同目录项中的NetworkAddress中。

(2)修改MAC

修改NetworkAddress中的值

(3)重启网卡

重启网卡也采用命令行方式:

netsh interface set interface "连接名称" DISABLE  //使网卡失效
netsh interface set interface "连接名称" ENABLE   //启动网卡

五.细节问题处理

5.1 命令行方式修改产生的console窗口问题

采用命令行方式来修改IP,首先想到的是system("命令");但这种方式执行指令的时候会弹出console窗口,显然用户体验降低;那如何屏蔽窗口呢? 采用ShellExcuteEx,可以创建一个新的进程去执行修改命令,并且在程序中适用WaitForSingleObject等待进程结束。
//启动cmd执行 netsh命令,并等待命令结束
void CIpChangeDlg::ExcuteCommand(char* pCommandParam)
{//初始化shellexe信息SHELLEXECUTEINFO   ExeInfo; ZeroMemory(&ExeInfo, sizeof(SHELLEXECUTEINFO)); ExeInfo.cbSize = sizeof(SHELLEXECUTEINFO); ExeInfo.lpFile = "cmd.exe"; ExeInfo.lpParameters = pCommandParam;ExeInfo.fMask = SEE_MASK_NOCLOSEPROCESS; ExeInfo.nShow = SW_HIDE; ExeInfo.hwnd = NULL;ExeInfo.lpVerb = NULL;ExeInfo.lpDirectory = NULL;ExeInfo.hInstApp = NULL;  //执行命令ShellExecuteEx(&ExeInfo);//等待进程结束WaitForSingleObject(ExeInfo.hProcess, INFINITE);
}

5.2 窗口假死问题

如果直接在按钮按下响应消息中执行命令,命令执行期间窗口将假死(因为消息循环因命令执行而阻塞);通过创建新的线程去进行修改操作,并在线程执行结束后,发送一个自定义消息WM_MSG_MODIFY_COMPLETE(表示命令执行结束)。

修改IP、DNS、MAC工具VC源码实现相关推荐

  1. 获取网关IP和MAC 的VB源码

    '窗体上加入控件command1,然后复制下面代码,运行,按command1即可. Option Explicit Private Declare Function OpenProcess Lib & ...

  2. Windows用户层技术工具与源码分享

    Windows用户层技术工具与源码分享 文章目录 Windows用户层技术工具与源码分享 一.注入与隐藏 1.窗口界面介绍 2.远程线程注入 3.APC注入 4.突破SESSION0隔离的远程注入 5 ...

  3. 票据打印, 银行账单打印, 标签印刷, 文档打印, 条码打印, 批量打印, 包装纸打印与设计,可变数据打印,数据库印刷,HMI报表打印,VC++源码库解决方案

    票据打印, 银行账单打印, 标签印刷, 文档打印, 条码打印, 批量打印, 包装纸打印与设计,可变数据打印,数据库印刷,HMI报表打印,VC++源码库解决方案 -- 全球领先.100%源码全开放.可用 ...

  4. Mac系统Spring源码导入

    Mac系统Spring源码导入 前言 工具准备 Gradle5.6.4安装 Spring-Framework5.2.8 Kotlin插件 spring-framework配置 修改settings.g ...

  5. [转] 用Diff和Patch工具维护源码

    在Unix系统下,维护源码版本可以使用很多方法,其中最常用的当然是大名鼎鼎的CVS,但实际上,简单的版本维护工作并没有必要使用复杂的CVS等专门的版本维护工具,Unix标配中的diff和patch工具 ...

  6. H5类似易企秀/编辑器/页面制作/开发/生成工具/软件/源码/授权

    代码地址如下: http://www.demodashi.com/demo/14960.html 项目简介 H5DS (HTML5 Design software) 这是一款基于WEB的 H5制作工具 ...

  7. 微信小程序:装B神器P图修改微信流量主小程序源码下载趣味恶搞图制作免服务器域名

    今天给大家带来的这一款小程序是装逼生成,趣味制图工具 该小程序免服务器和域名,低成本运营 内容丰富,搭建简单,而且更逼真哟 内涵N种模板制作,另外还可以设置推荐小程序更好的互引 简单说几个模板吧 红包 ...

  8. IEC61131, IEC61499图形可视化,PLC图形可视化,PLC组态,VBScript和JavaScript脚本,解决方案源代码, 开发平台100% VC++源码2018!

    IEC61131, IEC61499图形可视化,PLC图形可视化,PLC组态,VBScript和JavaScript脚本,解决方案源代码, 开发平台100% VC++源码2018! -- 全球领先. ...

  9. python外汇交易源码_Dukascopy外汇官方高质量Tick数据下载工具python源码

    dks_data_tool.gz (1.93 KB, 需要: RMB 18 元) 2015-11-14 10:43:51 上传 外汇高品质tickdata下载工具Python源码 需要: RMB 18 ...

  10. 286合购网VC++源码免杀

    286合购网VC++源码免杀 下载地址 https://pan.baidu.com/s/15qZCkizDDaK1Mq61a4T35g 创业资料/视频资料/安全相关 扫码下面二维码关注公众号回复 10 ...

最新文章

  1. arraylist从大到小排序_JAVA零基础入门课程笔记----数组排序
  2. opencv4.4.0函数手册_实战 MySQL8.0 窗口函数的巧妙应用
  3. Go 从入门到精通(三)字符串,时间,流程控制,函数
  4. Codeforces 429B Working out:dp【枚举交点】
  5. Error:unsupported class file version 52.0问题的解决
  6. IOS:批量导入图片和视频到模拟器的相册
  7. html背景图片尺寸位置百分比,css – 如何计算背景大小百分比?
  8. Skill Level 4 D23
  9. Vue的mergeOptions函数分析-下
  10. 【Spring-DEBUG记录】Dependency ‘org.aspectj:aspectjweaver:‘ not found
  11. win10配置jdk11
  12. mysql数据库的基本操作
  13. jxl获取excel超级链接
  14. C++ for循环的几种使用方法
  15. 领导层必看:要想公司管理好,办公软件少不了
  16. 及时尽孝,别枉读了大学
  17. python大学生社团管理系统django548
  18. 经济学知识——LPR、MLF、SLF、SLO、PSL、OMO
  19. 利用shell求取两个文件的交集、差集、并集等
  20. Python实现消消乐小游戏

热门文章

  1. 利用路由器实现VLAN
  2. matlab对列矢量求方差,matlab 求标准差 std函数用法
  3. 联想官方出品小工具:关闭或开启 Win10 系统自动更新
  4. 【SemiDrive源码分析】【驱动BringUp】40 - Touch Panel 触摸屏调试 (Android侧)
  5. 微型计算机的硬件原理图,电脑硬件基础图解
  6. C# Color颜色RGB对照表
  7. u8反启用固定资产_用友怎么取消固定资产模块
  8. 低压电气控制技能实训装置
  9. python生成3d人体模型_无限想象空间,用Python玩转3D人体姿态估计
  10. 思科交换机配置dhcp