VC准确地获取真实网络连接的名字(本地连接)
来源:互联网 发布:黑科技网络验证破解版 编辑:程序博客网 时间:2024/05/01 01:50
因为虚拟机和vpn软件会创建网络连接,电脑就有可能有多个网络连接,用程序获取真实的操作系统的网络连接就比较困难。
原理:注册表项HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards下面会有子键,里面记录的是系统创建的对应真实网卡的网络连接的名字,但是这个名字不太友好,要做转换。
获取到了本地连接的名字之后,再配合netsh命令就可以干很多事情了,比如程序修改网卡的dns服务器地址。
上VC代码:控制台程序,可直接编译测试
目前在xp、win7、win8和win10上面测试了一遍,结果都准确。
// QueryKey - Enumerates the subkeys of key and its associated values.// hKey - Key whose subkeys and values are to be enumerated.#include <windows.h>#include <stdio.h>#include <tchar.h>#include <Iphlpapi.h>#include <Mprapi.h>#include <string>#include <vector>#include <map>#include <iostream>#include <locale.h>#pragma comment(lib,"Iphlpapi.lib")#pragma comment(lib, "Mprapi.lib")using namespace std;#define MAX_KEY_LENGTH 255#define MAX_VALUE_NAME 16383//网卡名字与连接名字的对应关系,key为网卡名字,value为连接名字map<wstring, wstring> mapAdapterNames;const TCHAR NETWORKCARDS[MAX_KEY_LENGTH] = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards");void QueryKey(HKEY hKey) { TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey nameDWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys=0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey(hKey, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // Enumerate the subkeys, until RegEnumKeyEx fails.if (cSubKeys){printf( "\nNumber of subkeys: %d\n", cSubKeys);for (i=0; i<cSubKeys; i++) { cbName = MAX_KEY_LENGTH;retCode = RegEnumKeyEx(hKey, i,achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime); if (retCode == ERROR_SUCCESS) {_tprintf(TEXT("(%d) %s\n"), i+1, achKey);}}} // Enumerate the key values. if (cValues) {printf( "\nNumber of values: %d\n", cValues);for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) { cchValue = MAX_VALUE_NAME; achValue[0] = '\0'; retCode = RegEnumValue(hKey, i, achValue, &cchValue, NULL, NULL,NULL,NULL);if (retCode == ERROR_SUCCESS ) { _tprintf(TEXT("(%d) %s\n"), i+1, achValue); } }}}void QuerySubKeyValue(HKEY hKey) { TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey nameDWORD cbName; // size of name string TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name DWORD cchClassName = MAX_PATH; // size of class string DWORD cSubKeys=0; // number of subkeys DWORD cbMaxSubKey; // longest subkey size DWORD cchMaxClass; // longest class string DWORD cValues; // number of values for key DWORD cchMaxValue; // longest value name DWORD cbMaxValueData; // longest value data DWORD cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime; // last write time DWORD i, retCode; TCHAR achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey(hKey, // key handle achClass, // buffer for class name &cchClassName, // size of class string NULL, // reserved &cSubKeys, // number of subkeys &cbMaxSubKey, // longest subkey size &cchMaxClass, // longest class string &cValues, // number of values for this key &cchMaxValue, // longest value name &cbMaxValueData, // longest value data &cbSecurityDescriptor, // security descriptor &ftLastWriteTime); // last write time // Enumerate the subkeys, until RegEnumKeyEx fails.if (cSubKeys){printf( "\nNumber of subkeys: %d\n", cSubKeys);for (i=0; i<cSubKeys; i++) { cbName = MAX_KEY_LENGTH;retCode = RegEnumKeyEx(hKey, i,achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime); if (retCode == ERROR_SUCCESS) {_tprintf(TEXT("(%d) %s\n"), i+1, achKey);//生成键名TCHAR szFullSubKeyName[MAX_KEY_LENGTH] = {0};_sntprintf(szFullSubKeyName,MAX_KEY_LENGTH,TEXT("%s\\%s"),NETWORKCARDS,achKey);//打开子键HKEY hSubKey;if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,szFullSubKeyName,0,KEY_READ,&hSubKey) == ERROR_SUCCESS){//查询键值TCHAR szSubKeyValue[MAX_VALUE_NAME] = {0};DWORD dwType = REG_NONE, dwResultSize=MAX_VALUE_NAME * sizeof(TCHAR);long lResult = RegQueryValueEx(hSubKey, _T("ServiceName"), 0, &dwType, (BYTE *)(szSubKeyValue), &dwResultSize);if ((lResult==ERROR_SUCCESS) && (dwType==REG_SZ))_tprintf(mapAdapterNames[szSubKeyValue].c_str());//_tprintf(szSubKeyValue);RegCloseKey(hSubKey);}}}}}wstring Ascii2Unicode(string astrsrc){int wideSize = ::MultiByteToWideChar(CP_ACP, 0, astrsrc.c_str(), -1, NULL, 0);if (wideSize == ERROR_NO_UNICODE_TRANSLATION)return L"";if(wideSize <= 0) return wstring(L"");//wchar_t *szbuffer = new wchar_t[nLength + 2];vector<wchar_t> resultString(wideSize);int conResult = ::MultiByteToWideChar(CP_ACP, 0, astrsrc.c_str(), -1, &resultString[0], wideSize);if(conResult != wideSize)return L"";return wstring(&resultString[0]);}//获取网卡名字与连接名字的对应关系void GetAdapterNamesMap(){/********************************************通过Iphlpapi库获取网卡信息********************************************/PIP_ADAPTER_INFO pIpAdapterInfo = (PIP_ADAPTER_INFO) malloc(sizeof(IP_ADAPTER_INFO));ULONG stSize = sizeof(IP_ADAPTER_INFO);int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); //获得其大小if (ERROR_BUFFER_OVERFLOW == nRel) //重新申请所需要的空间{free(pIpAdapterInfo);pIpAdapterInfo = (PIP_ADAPTER_INFO) malloc(stSize);nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); }/********************************************通过mprapi库获取连接名称*并通过index将网卡信息和连接名称相关联********************************************/HANDLE hMprConfig; //连接信息的句柄DWORD dwRet=0; //返回值PIP_INTERFACE_INFO plfTable = NULL; //接口信息表DWORD dwBufferSize=0; //接口信息表空间大小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 //遍历网卡信息链表,通过index匹配,找到对应关系for(PIP_ADAPTER_INFO pIpAdapterInfoCopy = pIpAdapterInfo; pIpAdapterInfoCopy != NULL; pIpAdapterInfoCopy = pIpAdapterInfoCopy->Next){if(pIpAdapterInfoCopy->Index == AdaptMap.Index){mapAdapterNames[Ascii2Unicode(pIpAdapterInfoCopy->AdapterName)] = szFriendName;break;}} } HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, plfTable);//删除网卡信息if(pIpAdapterInfo)free(pIpAdapterInfo);}void __cdecl _tmain(void){setlocale(LC_ALL, "chs");//首先获取网卡适配器的名字与本地连接名字的对应关系GetAdapterNamesMap();//再获取真实的网络连接的名字HKEY hKey;if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"),0,KEY_READ,&hKey) == ERROR_SUCCESS){QuerySubKeyValue(hKey);}RegCloseKey(hKey);system("pause");}
0 0
- VC准确地获取真实网络连接的名字(本地连接)
- 获取网络连接名称“本地连接”的两种方法
- VC获取当前电脑所有网络连接名字
- 找不到网络连接(本地连接)的解决方法
- Android 获取下载文件的真实名字
- Android 获取下载文件的真实名字
- Windows VC获取准确时间的方法
- 获取当前电脑所有网络连接名字
- 获取网络,本地连接的具体名称(Friendly Name)
- ios获取当前的网络状态, 获取当前连接的wifi名字
- ios获取当前的网络状态, 获取当前连接的wifi名字
- ios获取当前的网络状态, 获取当前连接的wifi名字
- VC中获取函数的真实地址
- iOS开发中获取当前网络的ip及连接wifi时wifi的名字
- 获取当前连接的wifi的名字
- 获取当前连接的wifi的名字
- 获取软连接指定的真实文件名
- 如何准确获取xib创建的autolayout布局下的view的真实frame
- 一个简单的计算器
- PowerShell介绍 第四回 比较符、逻辑符和运算符
- TCP/IP TIME_WAIT状态原理和服务端过多原因分析
- 如何打开API文档
- poj 1979 Red and Black
- VC准确地获取真实网络连接的名字(本地连接)
- ThinkPHP快速入门3-连贯操作,变量
- Erlang application配置之.app文件
- PowerShell介绍 第五回 字符串及其操作符
- ANT教程之四 Ant属性任务
- EM算法
- 结构体初识———结构体成员
- C# DataSet性能最佳实践
- 使用Drawable资源之使用ClipDrawable资源