add perf
This commit is contained in:
parent
5c8f902c11
commit
8e1a01215d
175
WinDevice/src/Utils/PerformanceTool.cpp
Normal file
175
WinDevice/src/Utils/PerformanceTool.cpp
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
//
|
||||||
|
// Created by zyz on 2024/9/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "PerformanceTool.h"
|
||||||
|
#include "../Utils/StringUtil.h"
|
||||||
|
#include <Psapi.h>
|
||||||
|
#include <TlHelp32.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <powersetting.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <numeric>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <psapi.h>
|
||||||
|
#include <string>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
#pragma comment(lib, "PowrProf.lib")
|
||||||
|
#pragma comment(lib, "pdh.lib")
|
||||||
|
|
||||||
|
WinDevice::PerformanceTool::PerformanceTool() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WinDevice::PerformanceTool::~PerformanceTool() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float WinDevice::PerformanceTool::GetAppCpuUsage(DWORD processId) {
|
||||||
|
return _GetAppCpuUsage(processId, _GetProcessName(processId));
|
||||||
|
}
|
||||||
|
|
||||||
|
float WinDevice::PerformanceTool::GetAppCpuUsage(const std::wstring &processName) {
|
||||||
|
return _GetAppCpuUsage(_GetProcessId(processName), processName);
|
||||||
|
}
|
||||||
|
|
||||||
|
float WinDevice::PerformanceTool::_GetAppCpuUsage(DWORD processId, const std::wstring &processName) {
|
||||||
|
HQUERY query;
|
||||||
|
PDH_HCOUNTER cpuCounter;
|
||||||
|
PDH_FMT_COUNTERVALUE counterVal;
|
||||||
|
TCHAR szCounterPath[MAX_PATH];
|
||||||
|
|
||||||
|
// 初始化PDH
|
||||||
|
if (PdhOpenQuery(NULL, 0, &query) != ERROR_SUCCESS) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造CPU计数器路径
|
||||||
|
_stprintf_s(szCounterPath, MAX_PATH, TEXT("\\Process V2(%s:%d)\\%% Processor Time"), WinDevice::Wstring2String(processName).c_str(), processId);
|
||||||
|
if (PdhAddCounter(query, szCounterPath, 0, &cpuCounter) != ERROR_SUCCESS) {
|
||||||
|
PdhCloseQuery(query);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PdhCollectQueryData(query);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 等待以获取更新数据
|
||||||
|
// 再次收集数据
|
||||||
|
PdhCollectQueryData(query);
|
||||||
|
|
||||||
|
// 读取计数器值
|
||||||
|
auto cpuUsage = 0.0;
|
||||||
|
auto result = PdhGetFormattedCounterValue(cpuCounter, PDH_FMT_DOUBLE, NULL, &counterVal);
|
||||||
|
if (result == ERROR_SUCCESS) {
|
||||||
|
cpuUsage = counterVal.doubleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理
|
||||||
|
// 关闭句柄
|
||||||
|
PdhRemoveCounter(cpuCounter);
|
||||||
|
PdhCloseQuery(query);
|
||||||
|
return cpuUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
float WinDevice::PerformanceTool::GetAppMemoryUsage(const std::wstring &processName) {
|
||||||
|
return _GetAppMemoryUsage(processName);
|
||||||
|
}
|
||||||
|
|
||||||
|
float WinDevice::PerformanceTool::GetAppMemoryUsage(DWORD processId) {
|
||||||
|
return _GetAppMemoryUsage(_GetProcessName(processId));
|
||||||
|
}
|
||||||
|
|
||||||
|
float WinDevice::PerformanceTool::_GetAppMemoryUsage(const std::wstring &processName) {
|
||||||
|
HQUERY query;
|
||||||
|
PDH_HCOUNTER memCounter;
|
||||||
|
PDH_FMT_COUNTERVALUE counterVal;
|
||||||
|
TCHAR szCounterPath[MAX_PATH];
|
||||||
|
|
||||||
|
// 初始化PDH
|
||||||
|
if (PdhOpenQuery(NULL, 0, &query) != ERROR_SUCCESS) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造内存计数器路径
|
||||||
|
_stprintf_s(szCounterPath, MAX_PATH, TEXT("\\Process(%s)\\%s"), processName.c_str(), TEXT("Working Set - Private"));
|
||||||
|
if (PdhAddCounter(query, szCounterPath, 0, &memCounter) != ERROR_SUCCESS) {
|
||||||
|
PdhCloseQuery(query);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PdhCollectQueryData(query);
|
||||||
|
|
||||||
|
auto memoryUsage = 0.0;
|
||||||
|
auto result = PdhGetFormattedCounterValue(memCounter, PDH_FMT_DOUBLE, NULL, &counterVal);
|
||||||
|
if (result == ERROR_SUCCESS) {
|
||||||
|
memoryUsage = counterVal.doubleValue / 1024.0 / 1024.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理
|
||||||
|
// 关闭句柄
|
||||||
|
PdhRemoveCounter(memCounter);
|
||||||
|
PdhCloseQuery(query);
|
||||||
|
return memoryUsage;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring WinDevice::PerformanceTool::_GetProcessName(DWORD processId) {
|
||||||
|
std::wstring processName = L"<unknown>"; // 使用 std::wstring
|
||||||
|
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
|
||||||
|
if (hProcess != nullptr) {
|
||||||
|
HMODULE hMod;
|
||||||
|
DWORD cbNeeded;
|
||||||
|
|
||||||
|
// 获取进程中的模块句柄
|
||||||
|
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
|
||||||
|
// 获取模块的可执行文件名
|
||||||
|
TCHAR name[MAX_PATH];
|
||||||
|
GetModuleBaseName(hProcess, hMod, name, sizeof(name) / sizeof(TCHAR));
|
||||||
|
|
||||||
|
// 去掉 .exe 后缀
|
||||||
|
TCHAR* dot = _tcsrchr(name, '.');
|
||||||
|
if (dot != nullptr && _tcscmp(dot, TEXT(".exe")) == 0) {
|
||||||
|
*dot = '\0'; // 将 '.' 及其后面的字符替换为 '\0'
|
||||||
|
}
|
||||||
|
|
||||||
|
processName = WinDevice::TCHARArrayToWString(name); // 转换为 std::wstring
|
||||||
|
}
|
||||||
|
CloseHandle(hProcess); // 确保在这里关闭句柄
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印进程名称
|
||||||
|
std::wcout << L"Current process name: " << processName << std::endl;
|
||||||
|
return processName; // 返回 std::wstring
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WinDevice::PerformanceTool::_GetProcessId(const std::wstring &processName) {
|
||||||
|
DWORD processId = 0;
|
||||||
|
//创建进程快照
|
||||||
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (hSnapshot == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESSENTRY32 pe;
|
||||||
|
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
|
// 遍历所有进程
|
||||||
|
if (Process32First(hSnapshot, &pe))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// 将进程名与目标进程名进行比较
|
||||||
|
if (_tcscmp(pe.szExeFile, WinDevice::Wstring2String(processName).c_str()) == 0)
|
||||||
|
{
|
||||||
|
processId = pe.th32ProcessID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (Process32Next(hSnapshot, &pe));
|
||||||
|
}
|
||||||
|
return processId;
|
||||||
|
}
|
47
WinDevice/src/Utils/PerformanceTool.h
Normal file
47
WinDevice/src/Utils/PerformanceTool.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Created by zyz on 2024/9/30.
|
||||||
|
//
|
||||||
|
#include <WTypesbase.h>
|
||||||
|
#include <Pdh.h>
|
||||||
|
#include <PdhMsg.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef WINDEVICE_PERFORMANCETOOL_H
|
||||||
|
#define WINDEVICE_PERFORMANCETOOL_H
|
||||||
|
|
||||||
|
namespace WinDevice {
|
||||||
|
|
||||||
|
struct AppUsageInfo {
|
||||||
|
DWORD processId;
|
||||||
|
std::string processName;
|
||||||
|
float cpuUsage;
|
||||||
|
float memoryUsage;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PerformanceTool {
|
||||||
|
public:
|
||||||
|
PerformanceTool();
|
||||||
|
~PerformanceTool();
|
||||||
|
float GetAppCpuUsage(DWORD processId);
|
||||||
|
float GetAppCpuUsage(const std::wstring& processName);
|
||||||
|
float GetAppMemoryUsage(DWORD processId);
|
||||||
|
float GetAppMemoryUsage(const std::wstring& processName);
|
||||||
|
// float GetCurrentAppCpuUsage();
|
||||||
|
// float GetCurrentAppMemoryUsage();
|
||||||
|
// WinDevice::AppUsageInfo GetCurrentAppUsage();
|
||||||
|
// WinDevice::AppUsageInfo GetAppUsage(DWORD processId);
|
||||||
|
// WinDevice::AppUsageInfo GetAppUsage(const std::wstring& processName);
|
||||||
|
// std::vector<WinDevice::AppUsageInfo> GetTopAppUsageInfo(int topCount);
|
||||||
|
// float GetTotalCpuUsage() const;
|
||||||
|
// float GetTotalMemoryUsage() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _GetAppCpuUsage(DWORD processId, const std::wstring &processName);
|
||||||
|
float _GetAppMemoryUsage(const std::wstring &processName);
|
||||||
|
std::wstring _GetProcessName(DWORD processId);
|
||||||
|
DWORD _GetProcessId(const std::wstring &processName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //WINDEVICE_PERFORMANCETOOL_H
|
70
WinDevice/src/Utils/StringUtil.cpp
Normal file
70
WinDevice/src/Utils/StringUtil.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//
|
||||||
|
// Created by zyz on 2024/9/30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef WINDEVICE_STRINGUTIL_CPP_H
|
||||||
|
#define WINDEVICE_STRINGUTIL_CPP_H
|
||||||
|
|
||||||
|
#include "StringUtil.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <string>
|
||||||
|
#include <locale>
|
||||||
|
#include <codecvt>
|
||||||
|
|
||||||
|
template<typename To, typename From>
|
||||||
|
To Convert(const From &input) {
|
||||||
|
std::wstring_convert<std::codecvt_utf8<typename From::value_type>, typename From::value_type> converter;
|
||||||
|
try {
|
||||||
|
return converter.to_bytes(input);
|
||||||
|
} catch (...) {
|
||||||
|
return To(); // 返回空对象
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string WinDevice::Wstring2String(const std::wstring &input) {
|
||||||
|
return Convert<std::string>(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string WinDevice::Wchar2String(const WCHAR *input) {
|
||||||
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
||||||
|
try {
|
||||||
|
return converter.to_bytes(input);
|
||||||
|
} catch (...) {
|
||||||
|
return ""; // 返回空字符串表示失败
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring WinDevice::String2Wstring(const std::string &input) {
|
||||||
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
||||||
|
try {
|
||||||
|
return converter.from_bytes(input);
|
||||||
|
} catch (...) {
|
||||||
|
return L""; // 返回空宽字符串表示失败
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t *WinDevice::String2Wchar(const std::string &input) {
|
||||||
|
std::wstring wstr = String2Wstring(input);
|
||||||
|
if (wstr.empty()) {
|
||||||
|
return nullptr; // 转换失败时返回 nullptr
|
||||||
|
}
|
||||||
|
wchar_t *wcharStr = new wchar_t[wstr.length() + 1];
|
||||||
|
std::wcscpy(wcharStr, wstr.c_str());
|
||||||
|
return wcharStr; // 返回动态分配的 wchar_t*
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用转换函数
|
||||||
|
std::wstring WinDevice::TCHARArrayToWString(const TCHAR *tcharArray) {
|
||||||
|
#ifdef UNICODE
|
||||||
|
return std::wstring(tcharArray); // 如果是 Unicode,直接返回
|
||||||
|
#else
|
||||||
|
// 如果是 ANSI,进行转换
|
||||||
|
int size_needed = MultiByteToWideChar(CP_ACP, 0, tcharArray, -1, nullptr, 0);
|
||||||
|
std::wstring wstrName(size_needed, L'\0'); // 创建足够大小的 std::wstring
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, tcharArray, -1, &wstrName[0], size_needed);
|
||||||
|
return wstrName;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //WINDEVICE_STRINGUTIL_CPP_H
|
@ -1,22 +1,13 @@
|
|||||||
#include <string>
|
#pragma once
|
||||||
#include <locale>
|
#include <windows.h>
|
||||||
#include <codecvt>
|
#include <string>
|
||||||
|
|
||||||
namespace WinDevice {
|
namespace WinDevice {
|
||||||
|
|
||||||
template<typename To, typename From>
|
std::string Wstring2String(const std::wstring& input);
|
||||||
To Convert(const From& input) {
|
std::string Wchar2String(const WCHAR* input);
|
||||||
std::wstring_convert<std::codecvt_utf8<typename From::value_type>, typename From::value_type> converter;
|
std::wstring String2Wstring(const std::string& input);
|
||||||
return converter.to_bytes(input);
|
wchar_t* String2Wchar(const std::string& input);
|
||||||
}
|
std::wstring TCHARArrayToWString(const TCHAR* tcharArray);
|
||||||
|
|
||||||
std::string Wstring2String(const std::wstring& input) {
|
|
||||||
return Convert<std::string>(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Wchar2String(const WCHAR* input) {
|
|
||||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
|
||||||
return converter.to_bytes(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -2,11 +2,30 @@
|
|||||||
// Created by zyz on 2023/12/20.
|
// Created by zyz on 2023/12/20.
|
||||||
//
|
//
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
#include "Video/ScreenManager.h"
|
#include "Video/ScreenManager.h"
|
||||||
|
#include "Utils/PerformanceTool.h"
|
||||||
|
|
||||||
|
void getInfo() {
|
||||||
|
|
||||||
|
WinDevice::PerformanceTool performanceTool;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
std::cout << "App CPU Usage: " << performanceTool.GetAppCpuUsage(L"XYWinQT.pak") << "%" << std::endl;
|
||||||
|
|
||||||
|
// 每隔一秒采样一次(如果需要的话)
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
WinDevice::ScreenManager screenManager;
|
// WinDevice::ScreenManager screenManager;
|
||||||
screenManager.UpdateDisplayInfo();
|
// screenManager.UpdateDisplayInfo();
|
||||||
|
getInfo();
|
||||||
std::cout << "Press Enter to exit..." << std::endl; // 输出提示信息
|
std::cout << "Press Enter to exit..." << std::endl; // 输出提示信息
|
||||||
std::cin.get(); // 等待用户输入
|
std::cin.get(); // 等待用户输入
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user