调用C函数获取电脑信息及执行cmd命令时隐藏窗口

这篇博客介绍了如何在C/C++中调用函数获取电脑详细信息,包括操作系统、CPU、内存、GPU和硬件连接状态等,并在执行CMD命令时隐藏窗口,提供了一种无界面获取系统数据的方法。

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++】获取电脑硬件信息(操作系统,CPU,内存,GPU,显卡驱动,显示设备分辨率)

C语言获取硬件信息(CPU序列号,硬盘序列号,网卡IP、MAC地址、是否插入网线)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值