**最近有写一个运行再在Windows下的运维程序需求
运维程序exe通过读取ini文件匹配MAC地址来进行IP和计算机名的配置。我计划的实现思路逻辑如下:
目标Windows开机(IP及计算机名都是未配置状态) ---> 启动完成后运维程序exe运行 ---> 运维程序获取网卡MAC ---> 运维程序读取ini文件的所有MAC地址 ---> 将获取的网卡MAC地址与读取到的ini文件中的MAC进行匹配 ---> 匹配到条目则设置对应的IP和计算机名 --->完成退出
目前获取网卡MAC、配置IP、修改计算机名我都已经实现。问题在于MAC匹配上面。因为是INI文件,而非数据库表。假设MAC地址匹配了 aa-bb-cc-dd-ee-ff 如何让程序找到关联对应的IP和计算机名键值,即ip001键值和hostname001键值要跟mac001键值关联。是否还有其他的实现思路或INI文件设计方法,请有经验的师傅写个实例等等,谢谢~!!**
INI文件内容:
[config]
hostname001 = pc001
ip001 = 192.168.0.1
mac001 = aa-bb-cc-dd-ee-ff
hostname002 = pc002
ip002 = 192.168.0.2
mac002 = hh-ii-jj-kk-ll-mm
hostname003 = pc003
ip003 = 192.168.0.3
mac003 = nn-oo-pp-qq-rr-ss
建议用csv格式保存配置,这样可以用excel编辑,也可以用文本编辑器编辑,又方便程序读取
csv文件
pc001,192.168.0.1,aa-bb-cc-dd-ee-ff
pc002,192.168.0.2,hh-ii-jj-kk-ll-mm
pc003,192.168.0.3,nn-oo-pp-qq-rr-ss
读取代码
#include <stdio.h>
#include <string.h>
int main(){
char linebuf[512];
char hostname[64];
char ip[64];
char mac[64];
char* line;
int ret;
char* findmac = "hh-ii-jj-kk-ll-mm";
FILE* f = fopen("a.csv", "rb");
if(!f){
printf("file open error\n");
return -1;
}
while(1){
line = fgets(linebuf, 512, f);
if(!line)break;
if(*line == 0)continue;
ret = sscanf(line, "%[^,],%[^,],%s", hostname, ip, mac);
if(ret != 3)continue;
if(strcmp(mac, findmac) != 0)continue;
printf("found hostname=%s, ip=%s\n", hostname, ip);
fclose(f);
return 0;
}
printf("not found\n");
fclose(f);
return 1;
}
可以试试用json的方式配置config,方便配置多个host的属性,然后用rapidjson解析出来;
{
"host_array": [
{
"hostname": "pc001",
"ip": "192.168.0.1",
"mac": "aa-bb-cc-dd-ee-ff"
},
{
"hostname": "pc002",
"ip": "192.168.0.2",
"mac": "hh-ii-jj-kk-ll-mm"
},
{
"hostname": "pc003",
"ip": "192.168.0.3",
"mac": "nn-oo-pp-qq-rr-ss"
}
]
}
#include <iostream>
#include <cstdio>
#include <unordered_map>
#include "./rapidjson/include/rapidjson/filereadstream.h"
#include "./rapidjson/include/rapidjson/document.h"
int main()
{
rapidjson::Document docHandle;
FILE* fileHandle = fopen("./config.json", "r");
if (nullptr == fileHandle)
{
return -1;
}
fseek(fileHandle, 0, SEEK_END);
const auto fileSize = ftell(fileHandle);
fseek(fileHandle, 0, SEEK_SET);
char* buffer = new char[fileSize];
rapidjson::FileReadStream fileStream(fileHandle, buffer, fileSize);
docHandle.ParseStream(fileStream);
std::unordered_map<std::string, std::pair<std::string, std::string>> hostInfo;
if (docHandle.HasMember("host_array") && docHandle["host_array"].IsArray())
{
const auto &hostArray = docHandle["host_array"].GetArray();
for (size_t m = 0; m < hostArray.Size(); ++ m)
{
if (!hostArray[m].IsObject())
{
fclose(fileHandle);
delete[] buffer;
return -2;
}
const auto &valHost = hostArray[m].GetObject();
auto hostName = valHost["hostname"].GetString();
auto hostIp = valHost["ip"].GetString();
auto hostMac = valHost["mac"].GetString();
hostInfo.emplace(hostMac, std::make_pair(hostName, hostIp));
}
}
std::string matchedMac = "aa-bb-cc-dd-ee-ff";
if (hostInfo.end() != hostInfo.find(matchedMac))
{
hostInfo[matchedMac].first; // host name
hostInfo[matchedMac].second; // host ip
}
fclose(fileHandle);
delete[] buffer;
return 0;
}
或者ini标识一下多个host,比如
[hostCnt]
count=3
[host_1]
hostname = pc001
ip = 192.168.0.1
mac = aa-bb-cc-dd-ee-ff
[host_2]
hostname = pc002
ip = 192.168.0.2
mac = hh-ii-jj-kk-ll-mm
[host_3]
hostname = pc003
ip = 192.168.0.3
mac = nn-oo-pp-qq-rr-ss
不知道解决你的问题没有.
【以下回答由 GPT 生成】
根据您描述的问题,您需要使用GetPrivateProfileString函数从INI文件中读取与MAC地址匹配的IP和计算机名。以下是一个实现该功能的示例代码:
#include <iostream>
#include <Windows.h>
#include <string>
std::string getMACAddress()
{
std::string macAddress;
IP_ADAPTER_INFO adapterInfo[16];
DWORD bufferSize = sizeof(adapterInfo);
DWORD result = GetAdaptersInfo(adapterInfo, &bufferSize);
PIP_ADAPTER_INFO adapter = adapterInfo;
while (adapter)
{
macAddress = adapter->Address;
if (!macAddress.empty())
break;
adapter = adapter->Next;
}
return macAddress;
}
std::string getValueFromINI(const std::string& section, const std::string& key, const std::string& filename)
{
const int bufferSize = 255;
char buffer[bufferSize];
DWORD result = GetPrivateProfileString(section.c_str(), key.c_str(), "", buffer, bufferSize, filename.c_str());
return std::string(buffer);
}
bool setValueToINI(const std::string& section, const std::string& key, const std::string& value, const std::string& filename)
{
BOOL result = WritePrivateProfileString(section.c_str(), key.c_str(), value.c_str(), filename.c_str());
return result != 0;
}
int main()
{
std::string macAddress = getMACAddress();
std::string iniFilename = "config.ini";
std::string section = "config";
std::string key = "mac001";
std::string associatedIP = getValueFromINI(section, "ip001", iniFilename);
std::string associatedHostname = getValueFromINI(section, "hostname001", iniFilename);
if (macAddress == key)
{
// 找到匹配的MAC地址
std::cout << "匹配到MAC地址,关联的IP地址:" << associatedIP << std::endl;
std::cout << "关联的计算机名:" << associatedHostname << std::endl;
// 进一步实现其他操作,比如配置IP和计算机名
// ...
}
else
{
std::cout << "未找到对应的MAC地址" << std::endl;
}
return 0;
}
请注意,上述代码中使用了GetAdaptersInfo
函数来获取网卡的MAC地址,GetPrivateProfileString
函数从INI文件中读取键值。在main
函数中,您可以通过调用getValueFromINI
函数获取与MAC地址相关联的IP地址和计算机名,然后进行进一步的操作。
如果您需要在INI文件中添加、修改键值对,您可以使用setValueToINI
函数实现。
请确保将config.ini
替换为您实际使用的INI文件名。另外,该示例代码仅实现了部分功能,您可以根据需求进行进一步的开发和完善。