Created
June 9, 2024 09:10
-
-
Save Sryml/d28b6c4f77d5b93c046490bb19e49c81 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
msbuild CompatLayerAux.vcxproj /p:Configuration=Release /p:Platform=x86 | |
/t:Clean | |
/t:Rebuild | |
Usage: CompatLayerAux.exe <process_id> [to_lower (default: 1)] | |
*/ | |
#include <iostream> | |
#include <fstream> | |
#include <string> | |
#include <vector> | |
#include <windows.h> | |
#include <tchar.h> | |
#include <psapi.h> | |
// #include <algorithm> // for std::transform | |
// #include <cwctype> // for std::towlower | |
// #include <cctype> // for std::tolower | |
// #include <locale> // for std::locale, std::tolower | |
#include <codecvt> | |
// 定义一个结构体用于传递多个参数 | |
struct EnumParams | |
{ | |
DWORD processID = 0; | |
std::vector<HWND> windows; | |
}; | |
bool isConsoleAttached() | |
{ | |
return (GetConsoleWindow() != NULL); | |
} | |
std::vector<HWND> GetProcessWindows(DWORD processID) | |
{ | |
EnumParams params; | |
params.processID = processID; | |
// 回调函数用于枚举窗口 | |
auto enumWindowsProc = [](HWND hwnd, LPARAM lParam) -> BOOL | |
{ | |
EnumParams *params = reinterpret_cast<EnumParams *>(lParam); | |
DWORD windowProcessID; | |
GetWindowThreadProcessId(hwnd, &windowProcessID); | |
if (windowProcessID == params->processID) | |
{ | |
if (IsWindowVisible(hwnd)) | |
{ | |
params->windows.push_back(hwnd); | |
} | |
// TCHAR title[256]; | |
// if (GetWindowText(hwnd, title, sizeof(title) / sizeof(TCHAR))) | |
// { | |
// if (IsWindowVisible(hwnd) && _tcslen(title) > 0) | |
// { | |
// params->windows.push_back(hwnd); | |
// } | |
// } | |
} | |
return TRUE; | |
}; | |
EnumWindows(enumWindowsProc, reinterpret_cast<LPARAM>(¶ms)); | |
return params.windows; | |
} | |
// int main(int argc, char* argv[]) { | |
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) | |
{ | |
int argc = __argc; | |
char **argv = __argv; | |
// 创建输出文件路径 | |
WCHAR buffer[MAX_PATH]; | |
GetModuleFileName(NULL, buffer, MAX_PATH); | |
std::wstring filePath = std::wstring(buffer); | |
// std::size_t pos = filePath.find_last_of(L"\\/"); | |
std::size_t pos = filePath.find_last_of(L"."); | |
std::wstring exeDir = filePath.substr(0, pos); | |
std::wstring outputPath = exeDir + L".log"; | |
// 打开输出文件 | |
std::ofstream outfile(outputPath, std::ios::binary); | |
if (!outfile) | |
{ | |
if (isConsoleAttached()) | |
{ | |
std::cerr << "Failed to open output file" << std::endl; | |
} | |
return 1; | |
} | |
if (!isConsoleAttached()) | |
{ | |
std::cerr.rdbuf(outfile.rdbuf()); | |
std::cout.rdbuf(outfile.rdbuf()); | |
} | |
if (argc == 1) | |
{ | |
std::cerr << "error: invalid arguments" << std::endl; | |
std::cerr << "Usage: " << "CompatLayerAux.exe" << " <process_id> [to_lower (default: 1)]" << std::endl; | |
return 1; | |
} | |
DWORD processID = std::stoi(argv[1]); | |
bool arg_toLower = true; | |
if (argc > 2) | |
{ | |
arg_toLower = (std::stoi(argv[2]) != 0); | |
} | |
// 获取该进程的所有窗口句柄 | |
std::vector<HWND> windows = GetProcessWindows(processID); | |
if (windows.empty()) | |
{ | |
std::cerr << "error: no windows found for process " << processID << std::endl; | |
} | |
else | |
{ | |
// 写入窗口标题到文件 | |
for (HWND hwnd : windows) | |
{ | |
// 获取窗口标题长度 | |
const int length = GetWindowTextLengthW(hwnd); | |
if (length == 0) | |
{ | |
continue; | |
} | |
// 创建一个缓冲区来存储窗口标题 | |
std::wstring title(length + 1, L'\0'); | |
GetWindowTextW(hwnd, &title[0], length + 1); | |
// 去除终止符 | |
if (!title.empty()) | |
title.pop_back(); | |
// 将wstring转换为UTF-8字符串 | |
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; | |
std::string utf8Title = conv.to_bytes(title); | |
// 遍历字符串并逐个字符转换为小写 | |
for (char &c : utf8Title) | |
{ | |
c = std::tolower(c); | |
} | |
// std::cout << "length of title: " << title.length() << std::endl; | |
// std::cout << "title: " << utf8Title << std::endl; | |
if (utf8Title.find("console") == std::string::npos) | |
{ | |
// 忽略控制台窗口 | |
outfile << (arg_toLower ? utf8Title : conv.to_bytes(title)) << std::endl; | |
} | |
} | |
} | |
outfile.close(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment