windows api實現計算機空閒關機
阿新 • • 發佈:2019-02-06
1.實現監聽全域性的滑鼠和鍵盤事件,2分鐘不動則關機
2.實現計算機基本資訊和效能資訊的獲取,比如C盤利用率,CPU利用率,記憶體利用率等等
3.開闢新的執行緒
完整程式碼如下:
#include <windows.h> #include <time.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <tchar.h> #define GB(x) (((x).HighPart << 2) + ((DWORD)(x).LowPart) / 1024.0 / 1024.0 / 1024.0) typedef long long int64_t; typedef unsigned long long uint64_t; HWND hgWnd; HHOOK myhook; HHOOK myhookForKeyboard; long time0=0,time1=0; //MSG Msg; /*int get_io_bytes(uint64_t* read_bytes, uint64_t* write_bytes) { IO_COUNTERS io_counter; if(GetProcessIoCounters(GetCurrentProcess(), &io_counter)) { if(read_bytes) *read_bytes = io_counter.ReadTransferCount; if(write_bytes) *write_bytes = io_counter.WriteTransferCount; return 0; } return -1; } */ /*char* GetUserName(void) { const int nBufSize = 30; char chBuf[nBufSize]; ZeroMemory(chBuf,nBufSize); //獲取當前登入使用者的名稱 DWORD dwRet = nBufSize; if (::GetUserName(chBuf,&dwRet)) { // OutputDebugString(chBuf); } else { OutputDebugString(_T("獲取登入使用者名稱稱出錯!")); } OutputDebugString(_T("/r/n")); return chBuf; }*/ /*void TcharToChar (const TCHAR * tchar, char * _char) { int iLength ; //獲取位元組長度 iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL); //將tchar值賦給_char WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL); } char* GetPCName() { const int nBufSize = MAX_COMPUTERNAME_LENGTH + 1; TCHAR chBuf[nBufSize]; ZeroMemory(chBuf,nBufSize); //獲取當前計算機的名稱 DWORD dwRet = nBufSize; GetComputerName(chBuf,&dwRet); char charBuf[nBufSize]; TcharToChar(chBuf,charBuf); return charBuf; }*/ /*//獲取實時網速 int WIN_GetIfTable(WIN_IfTable& lstIf) { // GetAdaptersAddresses // 網口資訊, 準備1個足夠大的buf struct { DWORD dwNumEntries; MIB_IFROW table[8]; }myIfTable; memset(&myIfTable, 0, sizeof(myIfTable)); // DWORD nNumOfIf = 0; // DWORD ret = GetNumberOfInterfaces(&nNumOfIf); ULONG nBufSize = sizeof(myIfTable); DWORD ret = GetIfTable((MIB_IFTABLE*)&myIfTable, &nBufSize, TRUE); if( ret == 0) { for(int i=0; i<myIfTable.dwNumEntries; i++) { WIN_IfEntry entry; MIB_IFROW* pRow = &myIfTable.table[i]; strcpy(entry.strName, ""); strcpy(entry.strDescr, (char*)pRow->bDescr); entry.nIndex = pRow->dwIndex; entry.nType = pRow->dwType; entry.nInOctets = pRow->dwInOctets; //pRow->dwInUcastPkts + pRow->dwInNUcastPkts; entry.nOutOctes = pRow->dwOutOctets; //pRow->dwOutUcastPkts + pRow->dwOutNUcastPkts; entry.nAdminStatus = pRow->dwAdminStatus; entry.nSpeed = pRow->dwSpeed; if(pRow->dwType == 6) lstIf.push_back(entry); } } return 0; } */ /// 獲得CPU的核數 int get_processor_number(/*int& dwNumberOfProcessors,*/) { SYSTEM_INFO info; GetSystemInfo(&info); //info.dwProcessorType; CPU型別 // //info.wProcessorLevel //info.wProcessorRevision //info.dwPageSize return (int)info.dwNumberOfProcessors; } //CPU利用率 __int64 CompareFileTime2(FILETIME time1, FILETIME time2) { //memcpy(<__int64>, &FILETIME, 8); __int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime; __int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime; return b - a; } double CpuUseage() { FILETIME idleTime; FILETIME kernelTime; FILETIME userTime; FILETIME m_preidleTime; FILETIME m_prekernelTime; FILETIME m_preuserTime; HANDLE hEvent = CreateEvent (NULL,FALSE,FALSE,NULL); GetSystemTimes(&idleTime, &kernelTime, &userTime); WaitForSingleObject( hEvent,200); GetSystemTimes(&m_preidleTime, &m_prekernelTime, &m_preuserTime); int idle = CompareFileTime2(m_preidleTime, idleTime); int kernel = CompareFileTime2(m_prekernelTime, kernelTime); int user = CompareFileTime2(m_preuserTime, userTime); if (kernel + user == 0) return 0.99; //(總的時間-空閒時間)/總的時間=佔用cpu的時間就是使用率 double cpu = abs((kernel + user - idle) * 100 / (kernel + user)); //m_preidleTime = idleTime; //m_prekernelTime = kernelTime; //m_preuserTime = userTime; return cpu; } void GetDiskInfo(float& totalHardDisk,float& freeHardDisk,float& hardDiskUsage){ ULARGE_INTEGER FreeBytesAvailableC, TotalNumberOfBytesC, TotalNumberOfFreeBytesC; GetDiskFreeSpaceEx(_T("C:"), &FreeBytesAvailableC, &TotalNumberOfBytesC, &TotalNumberOfFreeBytesC); totalHardDisk = GB(TotalNumberOfBytesC); freeHardDisk = GB(TotalNumberOfFreeBytesC); hardDiskUsage = 1- freeHardDisk / totalHardDisk; } void GetMemoryStatus(char* status){ //char bufPreCPU[5]; MEMORYSTATUSEX statex; statex.dwLength = sizeof(statex); GlobalMemoryStatusEx(&statex); sprintf(status, "總記憶體使用率:%ld%% ", statex.dwMemoryLoad); } //獲得系統名稱 void GetSystemName(char* osname) { char buf[128]; SYSTEM_INFO info; //用SYSTEM_INFO結構判斷64位AMD處理器 GetSystemInfo(&info); //呼叫GetSystemInfo函式填充結構 OSVERSIONINFOEX os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); strcpy(buf, "unknown OperatingSystem."); if (GetVersionEx((OSVERSIONINFO *)&os)) { //下面根據版本資訊判斷作業系統名稱 switch (os.dwMajorVersion)//判斷主版本號 { case 4: switch (os.dwMinorVersion)//判斷次版本號 { case 0: if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) strcpy(buf, "Microsoft Windows NT 4.0"); //1996年7月釋出 else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) strcpy(buf, "Microsoft Windows 95"); break; case 10: strcpy(buf, "Microsoft Windows 98"); break; case 90: strcpy(buf, "Microsoft Windows Me"); break; } break; case 5: switch (os.dwMinorVersion) //再比較dwMinorVersion的值 { case 0: strcpy(buf, "Microsoft Windows 2000"); //1999年12月釋出 break; case 1: strcpy(buf, "Microsoft Windows XP"); //2001年8月釋出 break; case 2: if (os.wProductType == VER_NT_WORKSTATION && info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { strcpy(buf, "Microsoft Windows XP Professional x64 Edition"); } else if (GetSystemMetrics(SM_SERVERR2) == 0) strcpy(buf, "Microsoft Windows Server 2003"); //2003年3月釋出 else if (GetSystemMetrics(SM_SERVERR2) != 0) strcpy(buf, "Microsoft Windows Server 2003 R2"); break; } break; case 6: switch (os.dwMinorVersion) { case 0: if (os.wProductType == VER_NT_WORKSTATION) strcpy(buf, "Microsoft Windows Vista"); else strcpy(buf, "Microsoft Windows Server 2008"); //伺服器版本 break; case 1: if (os.wProductType == VER_NT_WORKSTATION) strcpy(buf, "Microsoft Windows 7"); else strcpy(buf, "Microsoft Windows Server 2008 R2"); break; } break; } }//if(GetVersionEx((OSVERSIONINFO *)&os)) strcpy(osname, buf); } LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam; const char *info = NULL; char text[50], data[20],tmp[60]; PAINTSTRUCT ps; HDC hdc; //MessageBox(NULL, TEXT("鍵盤被按下"), TEXT("鍵盤被按下"), MB_ICONEXCLAMATION | MB_OK); if (nCode >= 0) { //MessageBox(NULL, TEXT("內部鍵盤"), TEXT("內部鍵盤"), MB_ICONEXCLAMATION | MB_OK); hdc = GetDC(hgWnd); time1 = time(0); /*if(time0 != 0){ if(time1 - time0 > 120){ //info = "哈哈哈哈哈哈哈哈"; ZeroMemory(tmp, sizeof(tmp)); wsprintf(tmp, "keyBoard:time0 is %ld,time1 is %ld,time interval is %ld s", time0,time1,time1-time0); TextOut(hdc, 10, 70, tmp, strlen(tmp)); //system("shutdown -s -t 00") } }*/ time0 = time1; if (wParam == WM_KEYDOWN) info = "普通按鍵擡起"; else if (wParam == WM_KEYUP) info = "普通按鍵按下"; else if (wParam == WM_SYSKEYDOWN) info = "系統按鍵擡起"; else if (wParam == WM_SYSKEYUP) info = "系統按鍵按下"; int y = 10; char systemName[30]; ZeroMemory(systemName, sizeof(systemName)); GetSystemName(systemName); char title[60]; ZeroMemory(title, sizeof(title)); wsprintf(title, "按下任意鍵可以更新狀態(%s)",systemName); TextOut(hdc, 10, y, title, strlen(title)); y += 20; char bufPreCPU[30]; ZeroMemory(bufPreCPU, sizeof(bufPreCPU)); GetMemoryStatus(bufPreCPU); TextOut(hdc, 10, y, bufPreCPU, strlen(bufPreCPU)); y += 20; char diskUsage[30]; ZeroMemory(diskUsage, sizeof(diskUsage)); float a=0,b=0,c=0; GetDiskInfo(a,b,c); int ia = a; int ib = b; int ic = c*100; wsprintf(diskUsage, "C盤利用率:%d%%[%d GB / %d GB] ",ic,ia-ib,ia); //MessageBox(NULL, diskUsage, TEXT("錯誤"), MB_OK); TextOut(hdc, 10, y, diskUsage, strlen(diskUsage)); y += 20; char processNumber[30]; ZeroMemory(processNumber,strlen(processNumber)); int number = get_processor_number(); wsprintf(processNumber, "CPU核數:%d ",number); TextOut(hdc, 10, y, processNumber, strlen(processNumber)); y += 20; char cpuUsage[30]; ZeroMemory(processNumber,strlen(processNumber)); double dcpuUsage = CpuUseage(); int i = dcpuUsage; wsprintf(cpuUsage, "CPU利用率:%d%% ",i); TextOut(hdc, 10, y, cpuUsage, strlen(cpuUsage)); y += 20; ZeroMemory(text, sizeof(text)); ZeroMemory(data, sizeof(data)); wsprintf(text, "%s - 鍵盤碼 [%04d], 掃描碼 [%04d] ", info, p->vkCode, p->scanCode); wsprintf(data, "按鍵為: %c ", p->vkCode); TextOut(hdc, 10, y, text, strlen(text)); y += 20; TextOut(hdc, 10, y, data, strlen(data)); y += 20; //wsprintf(system, "CPU核數:%d",systemName); /*;*/ //double a = get_processor_number();//CpuUseage(); //uint64_t a,b,a1,b1; //get_io_bytes(&a,&b); //HANDLE hEvent = CreateEvent (NULL,FALSE,FALSE,NULL); //WaitForSingleObject( hEvent,200); //get_io_bytes(&a1,&b1); //char buffer[40]; //itoa(b,buffer, 10); //char* buffer = GetPCName(); //char* buffer = GetUserName(); //char* buffer = "hahahah"; //char mtmp[40]; //ZeroMemory(mtmp, sizeof(mtmp)); //wsprintf(mtmp, "name is %s", buffer); //TextOut(hdc, 10, 90, mtmp, strlen(mtmp)); ReleaseDC(hgWnd,hdc); } return CallNextHookEx(myhookForKeyboard, nCode, wParam, lParam); } /**************************************************************** WH_KEYBOARD hook procedure 滑鼠鉤子處理過程 ****************************************************************/ LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) { LPMSLLHOOKSTRUCT p = (LPMSLLHOOKSTRUCT)lParam; POINT pt = p->pt; DWORD mouseData = p->mouseData; //const char *info = NULL; char *info = NULL; char text[60], pData[50], mData[50],tmp[60]; PAINTSTRUCT ps; HDC hdc; if (nCode >= 0) { hdc = GetDC(hgWnd); time1 = time(0); /*if(time0 != 0){ if(time1 - time0 > 120){ //info = "哈哈哈哈哈哈哈哈"; ZeroMemory(tmp, sizeof(tmp)); wsprintf(tmp, "Mouse:time0 is %ld,time1 is %ld,time interval is %ld s", time0,time1,time1-time0); TextOut(hdc, 10, 70, tmp, strlen(tmp)); } } */ time0 = time1; //info = "aa"; //strftime(tmp, sizeof(tmp), "%Y/%m/%d %X %A 本年第%j天 %z",localtime(&t) ); //printf("%s",tmp); //char buffer[40]; //itoa( t, buffer, 10 ); if (wParam == WM_MOUSEMOVE) info = "滑鼠移動 "; else if(wParam == WM_LBUTTONDOWN) info = "滑鼠【左鍵】按下"; else if(wParam == WM_LBUTTONUP) info = "滑鼠【左鍵】擡起"; else if(wParam == WM_LBUTTONDBLCLK) info = "滑鼠【左鍵】雙擊"; else if(wParam == WM_RBUTTONDOWN) info = "滑鼠【右鍵】按下"; else if(wParam == WM_RBUTTONUP) info = "滑鼠【右鍵】擡起"; else if(wParam == WM_RBUTTONDBLCLK) info = "滑鼠【右鍵】雙擊"; else if(wParam == WM_MBUTTONDOWN) info = "滑鼠【滾輪】按下"; else if(wParam == WM_MBUTTONUP) info = "滑鼠【滾輪】擡起"; else if(wParam == WM_MBUTTONDBLCLK) info = "滑鼠【滾輪】雙擊"; else if(wParam == WM_MOUSEWHEEL) { info = "滑鼠【滾輪】滾動"; //system("shutdown -s -t 00"); } ZeroMemory(text, sizeof(text)); ZeroMemory(pData, sizeof(pData)); ZeroMemory(mData, sizeof(mData)); wsprintf( text, "當前狀態: %10s ", info); wsprintf(pData, "0x%x - X: [%04d], Y: [%04d] ", wParam, pt.x, pt.y); wsprintf(mData, "附帶資料: %16u ", mouseData); //GetSystemName(mData); //TextOut(hdc, 10, 10, text, strlen(text)); //TextOut(hdc, 10, 30, pData, strlen(pData)); //TextOut(hdc, 10, 50, mData, strlen(mData)); ReleaseDC(hgWnd,hdc); } return CallNextHookEx(myhook, nCode, wParam, lParam); } // 5. 視窗過程處理 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { hgWnd = hwnd; switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } DWORD WINAPI ThreadProc1(LPVOID lpParam) { //printf("sub thread started\n"); while(1){ //for(int i = 0;i < 3;i++){ //if(time(0) - time0 > 100){ //OutputDebugString("hehe");//system("shutdown -s -t 00"); //} char c[8]; int interval = time(0) - time0; itoa(interval,c,10); if((time0 != 0) && (interval > 120)) { system("shutdown -s -t 00");//MessageBox(NULL, TEXT(c), TEXT(c),MB_ICONEXCLAMATION | MB_OK); } Sleep(10000); } //} //printf("sub thread finished\n"); return 0; } /*DWORD WINAPI ThreadProc2(LPVOID lpParam) { while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return 0; } */ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; // http://baike.baidu.com/view/1750396.htm HWND hwnd; MSG Msg; char text[30]; const char szClassName[] = "myWindowClass"; // 1. 設定註冊視窗結構體 wc.cbSize = sizeof(WNDCLASSEX); // 註冊視窗結構體的大小 wc.style = 0; // 視窗的樣式 wc.lpfnWndProc = WndProc; // 指向視窗處理過程的函式指標 wc.cbClsExtra = 0; // 指定緊跟在視窗類結構後的附加位元組數 wc.cbWndExtra = 0; // 指定緊跟在視窗事例後的附加位元組數 wc.hInstance = hInstance; // 本模組的例項控制代碼 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 圖示的控制代碼 wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 游標的控制代碼 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景畫刷的控制代碼 wc.lpszMenuName = NULL; // 指向選單的指標 wc.lpszClassName = szClassName; // 指向類名稱的指標 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // 和視窗類關聯的小圖示 // 2. 使用【視窗結構體】註冊視窗 if(!RegisterClassEx(&wc)) { MessageBox(NULL, TEXT("視窗註冊失敗!"), TEXT("錯誤"), MB_ICONEXCLAMATION | MB_OK); return 0; } // 3. 建立視窗 hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, // 視窗的擴充套件風格 szClassName, // 指向註冊類名的指標 TEXT("關機工具 V1.0"), // 指向視窗名稱的指標 WS_OVERLAPPEDWINDOW, // 視窗風格 CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 視窗的 x,y 座標以及寬高 NULL, // 父視窗的控制代碼 NULL, // 選單的控制代碼 hInstance, // 應用程式例項的控制代碼 NULL // 指向視窗的建立資料 ); if(hwnd == NULL) { MessageBox(NULL, TEXT("視窗建立失敗"), TEXT("錯誤"),MB_ICONEXCLAMATION | MB_OK); return 0; } // 4. 顯示視窗 ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); // 設定滑鼠全域性監聽 myhook = SetWindowsHookEx( WH_MOUSE_LL, // 監聽型別【滑鼠】 MouseProc, // 處理函式 hInstance, // 當前例項控制代碼 0 // 監聽視窗控制代碼(NULL為全域性監聽) ); if(myhook == NULL) { wsprintf(text, "滑鼠監聽失敗!error : %d \n", GetLastError()); MessageBox(hwnd, text, TEXT("錯誤"), MB_OK); } // 設定鍵盤全域性監聽 myhookForKeyboard = SetWindowsHookEx( WH_KEYBOARD_LL, // 監聽型別【鍵盤】 KeyboardProc, // 處理函式 hInstance, // 當前例項控制代碼 0 // 監聽視窗控制代碼(NULL為全域性監聽) ); if(myhookForKeyboard == NULL) { wsprintf(text, "鍵盤監聽失敗!error : %d \n", GetLastError()); MessageBox(hwnd, text, TEXT("錯誤"), MB_OK); } DWORD threadID1; HANDLE hThread1; hThread1 = CreateThread(NULL,0,ThreadProc1,NULL,0,&threadID1); // 建立執行緒 //WaitForSingleObject(hThread1,INFINITE); // 5. 訊息迴圈 /* DWORD threadID2; HANDLE hThread2; hThread1 = CreateThread(NULL,0,ThreadProc2,NULL,0,&threadID2); // 建立執行緒 WaitForSingleObject(hThread2,INFINITE);*/ while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }