Skip to content

Instantly share code, notes, and snippets.

@Sryml
Created June 9, 2024 09:10
Show Gist options
  • Save Sryml/d28b6c4f77d5b93c046490bb19e49c81 to your computer and use it in GitHub Desktop.
Save Sryml/d28b6c4f77d5b93c046490bb19e49c81 to your computer and use it in GitHub Desktop.
/*
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>(&params));
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