C++ Log类 可获取常用硬件信息

log.h
#pragma once

#include "StdAfx.h"
#include <iostream>

class CLog
{
public:
	enum LogLevel // Log级别
	{
		lvInfo = 0, // 一般
		lvWarning = 1, // 警告
		lvError = 2 // 错误
	};

	CLog ();
	~CLog ();

	bool Open(LPCTSTR pszFileName);
	void Close(); // 关闭日志记录
	void Write(int nLogLevel, LPCTSTR pszFormat, ...); // 格式化写入日志信息

private:
	FILE* m_out;
};

log.cpp
#include "stdafx.h"
#include "Log.h"
#include <time.h>
#include <iostream>
#include <queue>
#include <stdarg.h>
#pragma  warning(disable:4996)

#ifdef _UNICODE
typedef wchar_t              char_t;
typedef std::wstring         string_t;
typedef std::wstringstream   stringstream_t;
#else
typedef char                 char_t;
typedef std::string          string_t;
typedef std::stringstream    stringstream_t;
#endif


// 格式化获取当前日期
static string_t GetTimeStr(LPCTSTR format)
{
	time_t t;
	time(&t);
	tm* time = localtime(&t);
	//"2011-07-18 23:03:01 ";
	//format = "%Y-%m-%d %H:%M:%S ";
	char_t strDate[50];
	_tcsftime(strDate, 30, format, time);
	return string_t(strDate);
}

// 获取操作系统版本信息
static string_t GetOSName()
{
	SYSTEM_INFO info = {0};
	ZeroMemory(&info, sizeof(info));
	GetSystemInfo(&info);

	OSVERSIONINFOEX os;
	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

	if (::GetVersionEx((OSVERSIONINFO*) & os))
	{
		string_t vname;
		// 判断主版本号
		switch (os.dwMajorVersion)
		{
		case 4:
			// 判断次版本号
			switch (os.dwMinorVersion)
			{
			case 0:
				if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
					// 1996年7月发布
					vname = _T("Microsoft Windows NT 4.0");
				else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
					vname = _T("Microsoft Windows 95");
				break;
			case 10:
				vname = _T("Microsoft Windows 98");
				break;
			case 90:
				vname = _T("Microsoft Windows Me");
				break;
			}
			break;
		case 5:
			// 再比较dwMinorVersion的值
			switch (os.dwMinorVersion)
			{
			case 0:
				// 1999年12月发布
				vname = _T("Microsoft Windows 2000");
				break;
			case 1:
				// 2001年8月发布
				vname = _T("Microsoft Windows XP");
				break;
			case 2:
				if (os.wProductType == VER_NT_WORKSTATION
						&& info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
					vname = _T("Microsoft Windows XP Professional x64 Edition");
				else if (GetSystemMetrics(SM_SERVERR2) == 0)
					vname = _T("Microsoft Windows Server 2003");
				// 2003年3月发布
				else if (GetSystemMetrics(SM_SERVERR2) != 0)
					vname = _T("Microsoft Windows Server 2003 R2");
				break;
			}
			break;
		case 6:
			switch (os.dwMinorVersion)
			{
			case 0:
				// VER_NT_WORKSTATION是桌面系统
				if (os.wProductType == VER_NT_WORKSTATION)
					vname = _T("Microsoft Windows Vista");
				else
					//服务器版本
					vname = _T("Microsoft Windows Server 2008");
				break;
			case 1:
				if (os.wProductType == VER_NT_WORKSTATION)
					vname = _T("Microsoft Windows 7");
				else
					vname = _T("Microsoft Windows Server 2008 R2");
				break;
			}
			break;
		default:
			vname=_T("未知操作系统");
		}
		WORD nSpVer = os.wServicePackMajor;
		char_t strSpVer[10];
		_itow_s(nSpVer, strSpVer, 10, 10);
		vname.append(L" SP").append(strSpVer);
		return vname;
	}
	else
		return _T("");
}

// 获取操作系统位数
static string_t GetOSBit()
{
	SYSTEM_INFO si;
	GetNativeSystemInfo(&si);
	if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
			si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
	{
		return string_t(_T("64位"));
	}
	else
	{
		return string_t(_T("32位"));
	}
}

// 获取IE浏览器版本
static string_t GetIEVer()
{
	char_t strVer[64];
	ULONG dwSize = 64;
	CRegKey keyVersion;
	try
	{
		LONG lResult = keyVersion.Open(HKEY_LOCAL_MACHINE,
									   TEXT("SOFTWARE\\Microsoft\\Internet Explorer"), KEY_READ);
		if (lResult != ERROR_SUCCESS)
			throw L"获取IE版本信息异常";
		LONG lResultQuery = keyVersion.QueryStringValue(
								TEXT("Version"), strVer, &dwSize);
		if (ERROR_SUCCESS != lResultQuery)
			return L"查询IE版本信息异常";
	}
	catch (char_t* ex)
	{
		std::wcout << ex << std::endl;
	}
	return string_t(strVer);
}

// 获取磁盘分区信息
static string_t GetDisksStr()
{
	string_t strDriv ;
	DWORD dw = GetLogicalDriveStrings(0,NULL);
	char_t* drivStr = (char_t*)HeapAlloc(
						  GetProcessHeap(), 0, dw * sizeof(TCHAR));
	GetLogicalDriveStringsW(dw,drivStr);

	int count = 0;
	while (count < 100)
	{
		if (drivStr[count] == _T(':'))
		{
			//char_t wc = drivStr[count];
			char_t buff[1];
			buff[0] = drivStr[count-1];
			strDriv.append(buff, 1);
			buff[0] = drivStr[count];
			strDriv.append(buff, 1);
			buff[0] = drivStr[count+1];
			strDriv.append(buff, 1);
			strDriv.append(L" ");
		}
		count++;
	}
	return strDriv;
}

// 获取内存大小
static string_t GetMemSize()
{
	string_t strMem;
	MEMORYSTATUS memStat; // 内存信息结构体
	ZeroMemory(&memStat, sizeof(memStat));
	memStat.dwLength = sizeof(memStat);
	GlobalMemoryStatus(&memStat);
	size_t totalPhys = memStat.dwTotalPhys / (1024*1024); // 总内存大小(MB)
	size_t availPhys = memStat.dwAvailPhys / (1024*1024); // 可用内存大小(MB)

	char_t strTotal[10];
	char_t strAvail[10];

	_ui64tow_s(totalPhys, strTotal, 10, 10);
	_ui64tow_s(availPhys, strAvail, 10, 10);

	strMem.append(_T("总内存大小: ")).append(strTotal).append(_T("M"));
	strMem.append(_T("    可用内存大小: ")).append(strAvail).append(_T("M"));

	return strMem;
}

// 获取CPU信息
static string_t GetCpuInfo()
{
	string_t strCpu;
	HKEY hKey;
#define BUFSIZE 80
	char_t szCpuInfo[BUFSIZE];
	DWORD szCpuFre = 0;
	DWORD dwBufLen = BUFSIZE;
	LONG lRet;

	lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
						 _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
						 0, KEY_QUERY_VALUE, &hKey);
	if ( lRet != ERROR_SUCCESS )
	{
		strCpu = _T("未知CPU类型");
	}
	else
	{
		lRet = RegQueryValueExW( hKey, _T("ProcessorNameString"), NULL, NULL,
								 (LPBYTE)szCpuInfo, &dwBufLen);
		if ( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) )
		{
			strCpu = _T("未知CPU类型");
		}
		else
		{
			strCpu = szCpuInfo;
			lRet = RegQueryValueEx(hKey, _T("~MHz"), NULL, NULL,
								   (LPBYTE) &szCpuFre, &dwBufLen);
		}
	}

	return strCpu;
}

// 获取当前线程所在路径
static string_t GetProcPath()
{
	char_t path[MAX_PATH];
	GetModuleFileNameW(NULL, path, MAX_PATH);
	return string_t(path);
}

// 获取磁盘使用情况
static string_t GetDisksFreeSpace()
{
	_ULARGE_INTEGER freespace, totalspace, userspace;
	string_t diskInfo;
	string_t strDisks = GetDisksStr();
	char_t buff[20] = {0};
	_tcscpy(buff, strDisks.c_str());
	std::queue <string_t> drivs;
	int index = 0;

	while (buff[index])
	{
		char_t driv[3] = {0};
		driv[0] = buff[index];
		driv[1] = buff[++index];
		index += 3;
		drivs.push(driv);
	}

	while (!drivs.empty())
	{
		string_t driv;
		driv = drivs.front();
		drivs.pop();
		GetDiskFreeSpaceExW(driv.c_str(), &userspace,
							&totalspace, &freespace);
		LONGLONG gByte = 1024 * 1024 * 1024;
		double dTotal = (double)((totalspace.QuadPart) / gByte);
		double dUse = (double)((userspace.QuadPart) / gByte);
		double dFree = (double)((freespace.QuadPart) / gByte);
		char_t drivInfo[100];
		swprintf(drivInfo, _T("\t%s    总大小:%4gG    已用:%4gG    可用:%4gG\n"),
				 driv.c_str(), dTotal, dUse, dFree);
		diskInfo.append(drivInfo);
	}
	return diskInfo;
}


//
// CLog 日志记录类

// 构造函数
CLog::CLog():m_out(NULL) {}

bool CLog::Open(LPCTSTR pszFileName)
{
	m_out = _tfopen(pszFileName, _T("a,ccs=UTF-8"));
	try
	{
		if (m_out == NULL)
			throw _T("打开log文件出错");

		fseek(m_out, 0, SEEK_END);
		long fsize = ftell(m_out);
		if (fsize <= 10)
		{
			string_t osName = GetOSName();           // 操作系统名称
			string_t osBit = GetOSBit();             // 操作系统位数(32/64)
			string_t ieVer = GetIEVer();             // IE版本
			string_t partition = GetDisksStr();      // 分区信息
			string_t diskInfo = GetDisksFreeSpace(); // 磁盘使用情况
			string_t memSize = GetMemSize();         // 内存大小
			string_t cpuInfo = GetCpuInfo();         // CPU信息s
			DWORD pId = GetCurrentThreadId();            // 当前线程ID
			string_t procPath = GetProcPath();       // 当前线程所在路径

			char* old_locale = _strdup(setlocale(LC_CTYPE,NULL) );
			setlocale(LC_CTYPE, "chs" );//设定
			LPCTSTR ex =  _T("写日志文件异常!");
			if (-1 == _ftprintf(m_out,
								L"--------------------------------------------------------------------\n"))
				throw ex;
			if (-1 == _ftprintf(m_out,
								L"%s%s %s\n", _T("[操作系统版本]\n\t"), osName.c_str(), osBit.c_str()))
				throw ex;
			if (-1 == _ftprintf(m_out,
								_T("[IE版本]\n\t%s%s\n"), _T("Internet Explorer "), ieVer.c_str()))
				throw ex;
			if (-1 == _ftprintf(m_out,
								_T("[磁盘分区]\n\t%s\n"), partition.c_str()))
				throw ex;
			if (-1 == _ftprintf(m_out,
								_T("[磁盘使用情况]\n%s"), diskInfo.c_str()))
				throw ex;
			if (-1 == _ftprintf(m_out,
								_T("[内存使用情况]\n\t%s\n"), memSize.c_str()))
				throw ex;
			if (-1 == _ftprintf(m_out,
								_T("[CPU信息]\n\t%s\n"), cpuInfo.c_str()))
				throw ex;
			if (-1 == _ftprintf(m_out,
								_T("[当前进程ID]\n\t%d\n"), pId))
				throw ex;
			if (-1 == _ftprintf(m_out,
								_T("[程序所在路径]\n\t%s\n"), procPath.c_str()))
				throw ex;

			if (-1 == _ftprintf(m_out,
								_T("--------------------------------------------------------------------\n")))
				throw ex;

			setlocale( LC_CTYPE, old_locale );
			free(old_locale);//还原区域设定
		}
	}
	catch (LPCTSTR /*ex*/)
	{
		//std::wcout << ex << std::endl;
		return false;
	}
	return true;
}

// 格式化写入日志信息 logLevel: 日志级别
void CLog::Write(int logLevel, LPCTSTR format, ...)
{
	va_list ap;
	va_start(ap, format);
	string_t logTime = GetTimeStr(_T("%Y-%m-%d %H:%M:%S"));
	try
	{
		char_t args[256] = {0};
		va_start(ap, format);
		_vstprintf(args, format, ap);

		string_t strLevel;

		switch (logLevel)
		{
		case CLog::lvInfo:
			strLevel = _T("Info");
			break;
		case CLog::lvWarning:
			strLevel = _T("Warn");
			break;
		case CLog::lvError:
			strLevel = _T("Error");
			break;
		}

		if (-1 == _ftprintf(m_out,_T("[%s] [%s] %s\n"),
							logTime.c_str(), strLevel.c_str(), args))
			throw L"写入日志出错!";

		va_end(ap);
	}
	catch (char_t* ex)
	{
		std::wcout << ex << std::endl;
	}
}

// 关闭记录文件
void CLog::Close()
{
	if (m_out != NULL)
	{
		fclose(m_out);
		m_out = NULL;
	}
}

CLog::~CLog()
{
	Close();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值