GetPCInfo.h
#include <iostream>
#include <string>
using namespace std;
//////////////////////////////////////////////////////////////////////////
wstring Str2Wstr(string str);
string ExecCmd(const char *cmd); // 执行 cmd 命令
void GetResultFromCmd(string & str); // 得到结果
//////////////////////////////////////////////////////////////////////////
void getNetworkInfo(char *local_ip, char *local_mac); // 获取IP、MAC
string GetPCInfo(); // 获取电脑相关信息
string GetCurrentDir();
//////////////////////////////////////////////////////////////////////////
// 获取两个日期的时间差
time_t convert(int year,int month,int day);
int get_days(const char* from, const char* to);
//////////////////////////////////////////////////////////////////////////
GetPCInfo.cpp
#include <iostream>
#include <string>
#include <winsock2.h> // include must before window.h
#include <iphlpapi.h>
#include <windows.h>
#include <DXGI.h>
#include <vector>
#pragma comment(lib, "iphlpapi.lib")
using namespace std;
// ---- get harddisk info ---- //
wstring Str2Wstr(string str)
{
unsigned len = str.size() * 2;// 预留字节数
setlocale(LC_CTYPE, ""); //必须调用此函数
wchar_t *p = new wchar_t[len];// 申请一段内存存放转换后的字符串
mbstowcs(p, str.c_str(), len);// 转换
std::wstring str1(p);
delete[] p;// 释放申请的内存
return str1;
}
string ExecCmd(string pszCmd)
{
wstring pszCmd_w = Str2Wstr(pszCmd);
wcout << "pszCmd_w is " << pszCmd_w << endl;
// 创建匿名管道,write->read;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
HANDLE hRead, hWrite;
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
cout << "@ CreatePipe failed!" << endl;
return (" ");
}
cout << "@0" << endl;
// 设置命令行进程启动信息(以隐藏方式启动命令并定位其输出到hWrite
STARTUPINFO si = { sizeof(STARTUPINFO) }; // Pointer to STARTUPINFO structure;
GetStartupInfo(&si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; //隐藏窗口;
si.hStdError = hWrite;
si.hStdError = hWrite;
si.hStdOutput = hWrite; //管道的输入端口连接命令行的输出;
// 启动命令行
PROCESS_INFORMATION pi;// Pointer to PROCESS_INFORMATION structure;
if (!CreateProcess(NULL,(LPWSTR)pszCmd_w.c_str(),
NULL,NULL,
TRUE,
//FALSE, // Set handle inheritance to FALSE
NULL,
//0, // No creation flags
NULL,
NULL,
&si,
&pi))
{
cout << "@ CreateProcess failed!" << endl;
return ("Cannot create process");
}
CloseHandle(hWrite);//关闭管道的输入端口;
// 读取命令行返回值
string strRetTmp;
char buff[1024] = { 0 };
DWORD dwRead = 0;
strRetTmp = buff;
while (ReadFile(hRead, buff, 1024, &dwRead, NULL))//从管道的输出端获取命令行写入的数据;
{
cout << "buff = " << buff << endl;
strRetTmp += buff;
}
CloseHandle(hRead);//关闭管道的输出端口;
return strRetTmp;
}
void GetResultFromCmd(string & str)
{
char buffer[512] = {0};
strcpy(buffer, str.data());
char *pLine = NULL;
char *next_token = NULL;
pLine = strtok_s(buffer, "\r\n", &next_token);
pLine = strtok_s(NULL, "\r\n", &next_token);
pLine = strtok_s(pLine, " ", &next_token);
str = pLine;
}
// ---- get network info ---- //
void getNetworkInfo(char *local_ip, char *local_mac)
{
// PIP_ADAPTER_INFO struct contains network information
PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
unsigned long adapter_size = sizeof(IP_ADAPTER_INFO);
int ret = GetAdaptersInfo(pIpAdapterInfo, &adapter_size);
if (ret == ERROR_BUFFER_OVERFLOW)
{
// overflow, use the output size to recreate the handler
delete pIpAdapterInfo;
pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[adapter_size];
ret = GetAdaptersInfo(pIpAdapterInfo, &adapter_size);
}
if (ret == ERROR_SUCCESS)
{
int card_index = 0;
// may have many cards, it saved in linklist
while (pIpAdapterInfo)
{
//cout << "---- " << "NetworkCard " << ++card_index << " ----" << endl;
//cout << "Network Card Name: " << pIpAdapterInfo->AdapterName << endl;
//cout << "Network Card Description: " << pIpAdapterInfo->Description << endl;
// get IP, one card may have many IPs
PIP_ADDR_STRING pIpAddr = &(pIpAdapterInfo->IpAddressList);
while (pIpAddr)
{
//char local_ip[128] = { 0 };
strcpy(local_ip, pIpAddr->IpAddress.String);
//cout << "Local IP: " << local_ip << endl;
pIpAddr = pIpAddr->Next;
}
//char local_mac[128] = { 0 };
int char_index = 0;
for (int i = 0; i < pIpAdapterInfo->AddressLength; i++)
{
char temp_str[10] = { 0 };
sprintf(temp_str, "%02X-", pIpAdapterInfo->Address[i]); // X for uppercase, x for lowercase
strcpy(local_mac + char_index, temp_str);
char_index += 3;
}
local_mac[17] = '\0'; // remove tail '-'
//cout << "Local Mac: " << local_mac << endl;
// here just need the first card info
break;
// iterate next
//pIpAdapterInfo = pIpAdapterInfo->Next;
}
}
if (pIpAdapterInfo)
delete pIpAdapterInfo;
}
string GetPCInfo()
{
string str = "";
char local_ip[128] = { 0 };
char local_mac[128] = { 0 };
getNetworkInfo(local_ip, local_mac);
cout << "IP:" << local_ip << endl;
cout << "MAC:" << local_mac << endl;
string str1 = ExecCmd("wmic cpu get processorid");
GetResultFromCmd(str1);
cout << "CPU:" << str1 << endl;
string str2 = ExecCmd("wmic bios get serialnumber");
GetResultFromCmd(str2);
cout << "BIOS:" << str2 << endl;
string str3 = ExecCmd("wmic baseboard get serialnumber");
GetResultFromCmd(str3);
cout << "CHIP:" << str3 << endl;
str = "CPU:" + str1 + "BIOS:" + str2 + "CHIP:" + str3;
return str;
}
string GetCurrentDir()
{
char szFilePath[MAX_PATH + 1] = { 0 };
GetModuleFileNameA(NULL, szFilePath, MAX_PATH);
/*
strrchr:函数功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置),
并返回这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。
使用这个地址返回从最后一个字符c到str末尾的字符串。
*/
(strrchr(szFilePath, '\\'))[0] = 0; // 删除文件名,只获得路径字串//
string path = szFilePath;
return path;
}
time_t convert(int year,int month,int day)
{
tm info={0};
info.tm_year=year-1900;
info.tm_mon=month-1;
info.tm_mday=day;
return mktime(&info);
}
int get_days(const char* from, const char* to)
{
int year,month,day;
sscanf(from,"%d-%d-%d",&year,&month,&day);
int fromSecond=(int)convert(year,month,day);
sscanf(to,"%d-%d-%d",&year,&month,&day);
int toSecond=(int)convert(year,month,day);
return (toSecond-fromSecond)/24/3600;
}
函数调用如下
#include "GetPCInfo.h"
bool Test::FileInit()
{
string path = GetCurrentDir(); // 获取当前目录
char sFile[512] = {0};
strcpy(sFile, path.data());
strcat(sFile, "/HWInfo.txt");
FILE *f = fopen(sFile, "rb");
if (!f)
{
return false;
}
fseek(f, 0L, SEEK_END);
size_t length = ftell(f);
char *content = new char[length + 1];
memset(content, 0, length);
rewind(f);
fread(content, sizeof(char), length, f); // 用于接收读取数据的缓冲区
content[length] = 0;
fclose(f);
char *res = InvCipherStrFromFileFormat(content, length);
char *pLine = NULL;
char *next_token = NULL;
// 可在此处理获取到的数据
list<string> infoList;
pLine = strtok_s((char*)res, "\r\n", &next_token);
while (pLine != NULL)
{
if (strstr (pLine, "-") != NULL)
{
break;
}
infoList.push_back(pLine);
pLine = strtok_s(NULL, "\r\n", &next_token);
}
if ((pLine = strtok_s(NULL, "\r\n", &next_token)) != NULL)
{
string temp = strstr (pLine, ":");
temp.erase(0, 1);
}
// 判断电脑是否被授权
bool bFlag = false;
string str = GetPCInfo();
list<string>::iterator ite = infoList.begin();
for (; ite != infoList.end(); ++ite)
{
string tmpStr = *ite;
if (tmpStr == str)
{
bFlag = true;
break;
}
}
if (!bFlag)
{
return false;
}
//////////////////////////////////////////////////////////////////////////
// 判断是否到期
//char sFile[512] = {0};
strcpy(sFile, path.data());
strcat(sFile, "/cfg");
FILE *fp = fopen(sFile, "rb");
if (!fp)
{
return 1;
}
fseek(fp, 0L, SEEK_END);
size_t len = ftell(fp);
char *data = new char[len + 1];
memset(data, 0, len);
rewind(fp);
fread(data, sizeof(char), len, f); // 用于接收读取数据的缓冲区
data[len] = 0;
fclose(fp);
char *pData = InvCipherStrFromFileFormat(data, len);
// 可在此处理获取到的数据
string sTime = "";
pLine = strtok_s((char*)pData, "\r\n", &next_token);
while (pLine != NULL)
{
char *temp = strstr (pLine, "lastRunTime:");
if (temp != NULL)
{
temp = strstr (pLine, " ");
sTime = temp;
sTime.erase(0, 1);
break;
}
pLine = strtok_s(NULL, "\r\n", &next_token);
}
if (!sTime.empty())
{
const char* from = sTime.data();
const char* to = m_pdata->sTimeV.data();
int days = get_days(from, to);
if (days < 0)
{
// 已过有效期
return false;
}
}
//////////////////////////////////////////////////////////////////////////
return true;
}
参考文章
这篇博客介绍了如何在C/C++中调用函数获取电脑详细信息,包括操作系统、CPU、内存、GPU和硬件连接状态等,并在执行CMD命令时隐藏窗口,提供了一种无界面获取系统数据的方法。

1万+

被折叠的 条评论
为什么被折叠?



