添加系统信息查看器代码

This commit is contained in:
zsyg
2025-06-28 11:58:36 +08:00
committed by GitHub
parent dcecf58f23
commit 021e89e3a4
24 changed files with 835 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
#include "about_dialog.h"
#include <tchar.h>
void show_about_dialog(HWND hParent) {
MessageBox(hParent,
_T("系统信息查看器\n版本 1.0\n\n一个简单的Windows系统信息工具"),
_T("关于"),
MB_OK | MB_ICONINFORMATION);
}

View File

@@ -0,0 +1,40 @@
#include "disk_info.h"
#include <tchar.h>
void get_disk_info(DiskInfo* disks, int* count) {
DWORD drives = GetLogicalDrives();
*count = 0;
for (char drive = 'A'; drive <= 'Z'; drive++) {
if (drives & (1 << (drive - 'A'))) {
TCHAR rootPath[4] = {drive, ':', '\\', '\0'};
TCHAR fileSystem[32];
DWORD serialNumber, maxComponentLength, fileSystemFlags;
if (GetVolumeInformation(
rootPath,
NULL, 0,
&serialNumber,
&maxComponentLength,
&fileSystemFlags,
fileSystem, sizeof(fileSystem))) {
DiskInfo* disk = &disks[(*count)++];
disk->driveLetter = drive;
ULARGE_INTEGER freeBytes, totalBytes, totalFreeBytes;
if (GetDiskFreeSpaceEx(
rootPath,
&freeBytes,
&totalBytes,
&totalFreeBytes)) {
disk->totalBytes = totalBytes.QuadPart;
disk->freeBytes = freeBytes.QuadPart;
}
strncpy(disk->fileSystem, fileSystem, sizeof(disk->fileSystem) - 1);
disk->fileSystem[sizeof(disk->fileSystem) - 1] = '\0';
}
}
}
}

View File

@@ -0,0 +1,41 @@
#include "logging.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
static const char* level_strings[] = {
"DEBUG",
"INFO",
"WARNING",
"ERROR"
};
void log_message(LogLevel level, const char* format, ...) {
va_list args;
va_start(args, format);
// 获取当前时间
time_t now;
time(&now);
struct tm* timeinfo = localtime(&now);
char time_str[20];
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", timeinfo);
// 格式化日志消息
char message[1024];
vsnprintf(message, sizeof(message), format, args);
// 输出到调试控制台
char output[2048];
snprintf(output, sizeof(output), "[%s] [%s] %s\n", time_str, level_strings[level], message);
OutputDebugStringA(output);
// 输出到文件
FILE* log_file = fopen("system_info.log", "a");
if (log_file) {
fprintf(log_file, "%s", output);
fclose(log_file);
}
va_end(args);
}

View File

@@ -0,0 +1,29 @@
#include <windows.h>
#include <tchar.h>
#include <locale.h>
#include "system_info.h"
#include "window_utils.h"
#include "logging.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
// 设置控制台编码为UTF-8
SetConsoleOutputCP(65001);
setlocale(LC_ALL, "chs");
// 初始化日志系统
log_message(LOG_INFO, "应用程序启动");
// 初始化系统信息收集
SystemInfo sysInfo;
init_system_info(&sysInfo);
// 创建并显示主窗口传递UTF-8编码标识
int result = create_main_window(hInstance, &sysInfo, 65001);
log_message(LOG_INFO, "应用程序退出");
return result;
}

View File

@@ -0,0 +1,55 @@
#include "main_window.h"
#include <tchar.h>
#include <commctrl.h>
#include <wchar.h>
#include <stdio.h>
#define IDC_INFO_TEXT 1002
void update_main_window(HWND hWnd, SystemInfo* sysInfo) {
HWND hInfoText = GetDlgItem(hWnd, IDC_INFO_TEXT);
if (!hInfoText) {
// 创建信息显示控件
hInfoText = CreateWindow(
_T("EDIT"),
_T(""),
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY,
20, 50, 800, 550,
hWnd,
(HMENU)IDC_INFO_TEXT,
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
NULL);
SendMessage(hInfoText, WM_SETFONT,
(WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
}
// 使用宽字符处理所有文本
wchar_t infoText[2048];
wchar_t cpuNameW[256];
MultiByteToWideChar(CP_UTF8, 0, sysInfo->cpuName, -1, cpuNameW, 256);
// 格式化系统信息,确保每个部分正确换行
swprintf(infoText, 2048,
L"===== 系统信息 =====\r\n\r\n"
L"[处理器信息]\r\n"
L"型号: %s\r\n"
L"物理核心数: %d\r\n"
L"逻辑核心数: %d\r\n\r\n"
L"[内存信息]\r\n"
L"总内存: %.2f GB\r\n"
L"可用内存: %.2f GB\r\n\r\n"
L"[操作系统]\r\n"
L"版本: Windows %d.%d\r\n"
L"构建版本号: %d\r\n",
cpuNameW,
sysInfo->cpuCores,
sysInfo->cpuThreads,
(float)sysInfo->memoryStatus.ullTotalPhys / (1024 * 1024 * 1024),
(float)sysInfo->memoryStatus.ullAvailPhys / (1024 * 1024 * 1024),
sysInfo->osVersion.dwMajorVersion,
sysInfo->osVersion.dwMinorVersion,
sysInfo->osVersion.dwBuildNumber);
SetWindowTextW(hInfoText, infoText);
}

View File

@@ -0,0 +1,85 @@
#include "network_info.h"
#include "config.h"
#include <stdio.h>
// 定义函数指针类型
typedef DWORD (WINAPI *GetAdaptersInfoFunc)(_Out_ PIP_ADAPTER_INFO, _Inout_ PULONG);
// 安全的函数指针转换函数
static FARPROC safe_get_proc_address(HMODULE module, const char* name) {
FARPROC proc = GetProcAddress(module, name);
if (!proc) {
return NULL;
}
return proc;
}
// 辅助宏用于安全的函数指针转换
#define GET_PROC_ADDRESS(module, name, type) \
((type)(void*)safe_get_proc_address(module, name))
void get_network_adapters(NetworkAdapterInfo* adapters, int* count) {
HMODULE hModule = LoadLibrary("iphlpapi.dll");
if (!hModule) return;
// 使用类型安全的函数指针转换
GetAdaptersInfoFunc pGetAdaptersInfo = GET_PROC_ADDRESS(hModule, "GetAdaptersInfo", GetAdaptersInfoFunc);
if (!pGetAdaptersInfo) {
FreeLibrary(hModule);
return;
}
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
*count = 0;
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == NULL) {
FreeLibrary(hModule);
return;
}
// 第一次调用获取缓冲区大小
if (pGetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
if (pAdapterInfo == NULL) {
FreeLibrary(hModule);
return;
}
}
if ((dwRetVal = pGetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
while (pAdapter && *count < MAX_ADAPTERS) {
NetworkAdapterInfo* adapter = &adapters[(*count)++];
// 复制适配器名称和描述
strncpy(adapter->adapterName, pAdapter->AdapterName, MAX_ADAPTER_NAME_LENGTH);
strncpy(adapter->description, pAdapter->Description, MAX_ADAPTER_DESCRIPTION_LENGTH);
// 格式化IP地址
if (pAdapter->IpAddressList.IpAddress.String[0] != '\0') {
strncpy(adapter->ipAddress, pAdapter->IpAddressList.IpAddress.String, 15);
adapter->ipAddress[15] = '\0';
} else {
strcpy(adapter->ipAddress, "N/A");
}
// 格式化MAC地址
sprintf(adapter->macAddress, "%02X:%02X:%02X:%02X:%02X:%02X",
pAdapter->Address[0], pAdapter->Address[1],
pAdapter->Address[2], pAdapter->Address[3],
pAdapter->Address[4], pAdapter->Address[5]);
adapter->speed = pAdapter->DhcpEnabled ? 100 : 10; // 简化处理,实际项目中应使用更精确的方法
pAdapter = pAdapter->Next;
}
}
free(pAdapterInfo);
}

View File

@@ -0,0 +1,137 @@
#include "performance_info.h"
#include <pdh.h>
#include <psapi.h>
#include "performance_info.h"
#include <windows.h>
#include <psapi.h>
// 定义函数指针类型
typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(_In_opt_ LPCSTR, _In_ DWORD_PTR, _Out_ PDH_HQUERY*);
typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(_In_ PDH_HQUERY, _In_ LPCSTR, _In_ DWORD_PTR, _Out_ PDH_HCOUNTER*);
typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(_In_ PDH_HQUERY);
typedef PDH_STATUS (WINAPI *PdhGetFormattedCounterValueFunc)(_In_ PDH_HCOUNTER, _In_ DWORD, _Out_opt_ LPDWORD, _Out_ PPDH_FMT_COUNTERVALUE);
// 安全的函数指针转换函数
static FARPROC safe_get_proc_address(HMODULE module, const char* name) {
FARPROC proc = GetProcAddress(module, name);
if (!proc) {
return NULL;
}
return proc;
}
// 辅助宏用于安全的函数指针转换
#define GET_PROC_ADDRESS(module, name, type) \
((type)(void*)safe_get_proc_address(module, name))
static PDH_HQUERY cpuQuery;
static PDH_HCOUNTER cpuTotal;
static HMODULE hPdhModule = NULL;
static PdhOpenQueryFunc pPdhOpenQuery = NULL;
static PdhAddCounterFunc pPdhAddCounter = NULL;
static PdhCollectQueryDataFunc pPdhCollectQueryData = NULL;
static PdhGetFormattedCounterValueFunc pPdhGetFormattedCounterValue = NULL;
void init_performance_counters() {
hPdhModule = LoadLibrary("pdh.dll");
if (!hPdhModule) {
return;
}
pPdhOpenQuery = GET_PROC_ADDRESS(hPdhModule, "PdhOpenQueryA", PdhOpenQueryFunc);
pPdhAddCounter = GET_PROC_ADDRESS(hPdhModule, "PdhAddCounterA", PdhAddCounterFunc);
pPdhCollectQueryData = GET_PROC_ADDRESS(hPdhModule, "PdhCollectQueryData", PdhCollectQueryDataFunc);
pPdhGetFormattedCounterValue = GET_PROC_ADDRESS(hPdhModule, "PdhGetFormattedCounterValue", PdhGetFormattedCounterValueFunc);
if (pPdhOpenQuery && pPdhAddCounter && pPdhCollectQueryData) {
// 初始化性能计数器
if (pPdhOpenQuery(NULL, 0, &cpuQuery) != ERROR_SUCCESS) {
return;
}
// 添加CPU计数器
if (pPdhAddCounter(cpuQuery, "\\Processor(_Total)\\% Processor Time", 0, &cpuTotal) != ERROR_SUCCESS) {
return;
}
// 第一次收集数据,用于初始化
pPdhCollectQueryData(cpuQuery);
Sleep(1000); // 等待1秒获取基准数据
pPdhCollectQueryData(cpuQuery);
}
}
void get_performance_info(PerformanceInfo* perfInfo) {
static BOOL initialized = FALSE;
if (!initialized) {
init_performance_counters();
initialized = TRUE;
}
// 获取CPU使用率
if (pPdhCollectQueryData && pPdhGetFormattedCounterValue) {
// 第一次收集数据作为基准
pPdhCollectQueryData(cpuQuery);
Sleep(1000); // 等待1秒
pPdhCollectQueryData(cpuQuery); // 第二次收集数据
PDH_FMT_COUNTERVALUE counterVal;
if (pPdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal) == ERROR_SUCCESS) {
perfInfo->cpuUsage = (DWORD)counterVal.doubleValue;
} else {
perfInfo->cpuUsage = 0;
}
} else {
// 如果PDH不可用使用GetSystemTimes作为备用方案
FILETIME idleTime, kernelTime, userTime;
if (GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
ULONGLONG idle = ((ULONGLONG)idleTime.dwHighDateTime << 32) | idleTime.dwLowDateTime;
ULONGLONG kernel = ((ULONGLONG)kernelTime.dwHighDateTime << 32) | kernelTime.dwLowDateTime;
ULONGLONG user = ((ULONGLONG)userTime.dwHighDateTime << 32) | userTime.dwLowDateTime;
static ULONGLONG prevIdle = 0, prevKernel = 0, prevUser = 0;
ULONGLONG idleDiff = idle - prevIdle;
ULONGLONG kernelDiff = kernel - prevKernel;
ULONGLONG userDiff = user - prevUser;
if (prevIdle != 0 && (kernelDiff + userDiff) > 0) {
perfInfo->cpuUsage = (DWORD)(100.0 - (100.0 * idleDiff) / (kernelDiff + userDiff));
} else {
perfInfo->cpuUsage = 0;
}
prevIdle = idle;
prevKernel = kernel;
prevUser = user;
} else {
perfInfo->cpuUsage = 0;
}
}
// 获取内存使用率
MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&memInfo);
// 使用GlobalMemoryStatusEx获取更精确的内存使用率
MEMORYSTATUSEX memStatus;
memStatus.dwLength = sizeof(memStatus);
GlobalMemoryStatusEx(&memStatus);
perfInfo->memoryUsage = memStatus.dwMemoryLoad;
// 获取进程和线程数量
PERFORMANCE_INFORMATION perfInfoStruct;
GetPerformanceInfo(&perfInfoStruct, sizeof(perfInfoStruct));
perfInfo->processesCount = perfInfoStruct.ProcessCount;
perfInfo->threadsCount = perfInfoStruct.ThreadCount;
perfInfo->handlesCount = perfInfoStruct.HandleCount;
}
void cleanup_performance_counters() {
if (hPdhModule) {
FreeLibrary(hPdhModule);
hPdhModule = NULL;
}
}

View File

@@ -0,0 +1,26 @@
#include "system_info.h"
#include <intrin.h>
void init_system_info(SystemInfo* sysInfo) {
// 获取CPU信息
int cpuInfo[4] = {0};
__cpuid(cpuInfo, 0x80000002);
memcpy(sysInfo->cpuName, cpuInfo, sizeof(cpuInfo));
__cpuid(cpuInfo, 0x80000003);
memcpy(sysInfo->cpuName + 16, cpuInfo, sizeof(cpuInfo));
__cpuid(cpuInfo, 0x80000004);
memcpy(sysInfo->cpuName + 32, cpuInfo, sizeof(cpuInfo));
// 获取系统信息
GetSystemInfo(&sysInfo->systemInfo);
sysInfo->cpuCores = sysInfo->systemInfo.dwNumberOfProcessors;
sysInfo->cpuThreads = sysInfo->cpuCores; // 简化处理
// 获取内存信息
sysInfo->memoryStatus.dwLength = sizeof(sysInfo->memoryStatus);
GlobalMemoryStatusEx(&sysInfo->memoryStatus);
// 获取操作系统版本
sysInfo->osVersion.dwOSVersionInfoSize = sizeof(sysInfo->osVersion);
GetVersionEx((LPOSVERSIONINFO)&sysInfo->osVersion);
}

View File

@@ -0,0 +1,45 @@
#include "system_tray.h"
#include <shellapi.h>
#include <strsafe.h>
void create_tray_icon(HWND hWnd, HICON hIcon) {
NOTIFYICONDATA nid = {0};
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = ID_TRAYICON;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uCallbackMessage = WM_TRAYICON;
nid.hIcon = hIcon;
#if defined(UNICODE) || defined(_UNICODE)
StringCbCopyW(nid.szTip, sizeof(nid.szTip), L"系统信息查看器");
#else
StringCbCopyA(nid.szTip, sizeof(nid.szTip), "系统信息查看器");
#endif
Shell_NotifyIcon(NIM_ADD, &nid);
}
void update_tray_icon(HWND hWnd, HICON hIcon, LPCTSTR tooltip) {
NOTIFYICONDATA nid = {0};
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = ID_TRAYICON;
nid.uFlags = NIF_ICON | NIF_TIP;
nid.hIcon = hIcon;
#if defined(UNICODE) || defined(_UNICODE)
StringCbCopyW(nid.szTip, sizeof(nid.szTip), tooltip);
#else
StringCbCopyA(nid.szTip, sizeof(nid.szTip), tooltip);
#endif
Shell_NotifyIcon(NIM_MODIFY, &nid);
}
void remove_tray_icon(HWND hWnd) {
NOTIFYICONDATA nid = {0};
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = ID_TRAYICON;
Shell_NotifyIcon(NIM_DELETE, &nid);
}

View File

@@ -0,0 +1,38 @@
#include "utils.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
char* wchar_to_mb(const wchar_t* wstr) {
if (!wstr) return NULL;
int size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* mbstr = (char*)malloc(size);
if (mbstr) {
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, mbstr, size, NULL, NULL);
}
return mbstr;
}
wchar_t* mb_to_wchar(const char* str) {
if (!str) return NULL;
int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
wchar_t* wstr = (wchar_t*)malloc(size * sizeof(wchar_t));
if (wstr) {
MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, size);
}
return wstr;
}
char* get_current_time_string() {
time_t now;
time(&now);
struct tm* timeinfo = localtime(&now);
char* time_str = (char*)malloc(20);
if (time_str) {
strftime(time_str, 20, "%Y-%m-%d %H:%M:%S", timeinfo);
}
return time_str;
}

View File

@@ -0,0 +1,102 @@
#include "window_utils.h"
#include "main_window.h"
#include <tchar.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#define IDC_MAIN_BUTTON 1001
// 全局变量存储系统信息
static SystemInfo* g_sysInfo = NULL;
BOOL register_window_class(HINSTANCE hInstance) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = MainWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = _T("SystemInfoWindowClass");
wcex.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
return RegisterClassEx(&wcex);
}
int create_main_window(HINSTANCE hInstance, SystemInfo* sysInfo, UINT codePage) {
// 设置控制台编码
if (codePage == 65001) {
SetConsoleOutputCP(65001);
_setmode(_fileno(stdout), _O_U16TEXT);
}
// 设置窗口标题为宽字符
LPCWSTR windowTitle = L"系统信息查看器";
g_sysInfo = sysInfo;
if (!register_window_class(hInstance)) {
return 0;
}
HWND hWnd = CreateWindowW(
L"SystemInfoWindowClass",
windowTitle,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
450, 300,
NULL, NULL, hInstance, NULL);
if (!hWnd) {
return 0;
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
// 初始更新窗口内容
update_main_window(hWnd, sysInfo);
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_CREATE: {
// 创建显示系统信息的按钮
CreateWindowW(L"BUTTON", L"刷新信息",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
10, 10, 150, 30,
hWnd, (HMENU)IDC_MAIN_BUTTON,
(HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE), NULL);
break;
}
case WM_COMMAND: {
if (LOWORD(wParam) == IDC_MAIN_BUTTON) {
// 刷新系统信息
init_system_info(g_sysInfo);
update_main_window(hWnd, g_sysInfo);
}
break;
}
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}