Assist.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. #include "Assist.h"
  2. #include <time.h>
  3. #include <locale.h>
  4. #include "CritSection.h"
  5. namespace Assist
  6. {
  7. int frameWidth = 2;//6
  8. int titleBarHeight = 27;//29
  9. ThreadSection g_csTextLog;
  10. TCHAR g_szCurModuleFileName[MAX_PATH];
  11. TCHAR g_szCurModuleDir[MAX_PATH];
  12. TCHAR g_szCurModulePath[MAX_PATH];
  13. TCHAR g_szFna[_MAX_FNAME];
  14. TCHAR g_szExt[_MAX_EXT];
  15. TCHAR g_szAssistConfig[MAX_PATH];
  16. std::string g_strAppdir;
  17. std::string g_strGameDir;
  18. TCHAR g_szGameApp[MAX_PATH];
  19. int nGameWndType;
  20. int nAttackCount = 0;
  21. void Init()
  22. {
  23. TCHAR szDrive[_MAX_DRIVE] = { 0 };
  24. TCHAR szDir[_MAX_DIR] = { 0 };
  25. TCHAR szFna[_MAX_FNAME] = { 0 };
  26. TCHAR szExt[_MAX_EXT] = { 0 };
  27. DWORD dwRet = ::GetModuleFileName(NULL, g_szCurModuleFileName, sizeof(g_szCurModuleFileName) / sizeof(TCHAR));
  28. _tsplitpath_s(g_szCurModuleFileName, szDrive, szDir, g_szFna, g_szExt);
  29. _tcscat_s(g_szCurModuleDir, MAX_PATH, szDrive);
  30. _tcscat_s(g_szCurModuleDir, MAX_PATH, szDir);
  31. //g_strAppdir = g_szCurModuleDir;
  32. _stprintf_s(g_szAssistConfig, _T("%s%s"), g_szCurModuleDir, _T("Assist.ini"));
  33. TCHAR szValue[MAX_PATH] = { 0 };
  34. GetPrivateProfileString(_T("Assist"), _T("GamePath"), _T(""), szValue, MAX_PATH, g_szAssistConfig);
  35. //g_strGameDir = szValue;
  36. GetPrivateProfileString(_T("Assist"), _T("GameApp"), _T(""), g_szGameApp, MAX_PATH, g_szAssistConfig);
  37. // 读取窗口类型;
  38. _stprintf_s(szValue, _T("%s%s"), g_szGameApp, _T("save\\config.ini"));
  39. int ScreenWidth = GetPrivateProfileInt(_T("SysCfg"), _T("ScreenWidth"), 640, szValue);
  40. // Alt+A次数;
  41. nAttackCount = GetPrivateProfileInt(_T("SysCfg"), _T("AttackCount"), 120, szValue);
  42. }
  43. void SetWindowForeground(HWND hWnd)
  44. {
  45. if (!IsWindow(hWnd))
  46. return;
  47. ::ShowWindow(hWnd, SW_SHOWNORMAL);
  48. ::SetForegroundWindow(hWnd); // 窗口前置才能单击成功;
  49. }
  50. bool IsWindowForeground(HWND hWnd)
  51. {
  52. return false;
  53. }
  54. bool StartApp(const TCHAR* szAppPath, const TCHAR* szAppArgs)
  55. {
  56. if (!PathFileExists(szAppPath))
  57. {
  58. WriteTextLog(_T("Error, %ls path not exists!\n"), szAppPath);
  59. return false;
  60. }
  61. SHELLEXECUTEINFO ShExecInfo;
  62. ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
  63. ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
  64. ShExecInfo.hwnd = NULL;
  65. ShExecInfo.lpVerb = _T("open");
  66. ShExecInfo.lpFile = szAppPath;
  67. ShExecInfo.lpParameters = szAppArgs;
  68. ShExecInfo.lpDirectory = NULL;
  69. ShExecInfo.nShow = SW_SHOW;
  70. ShExecInfo.hInstApp = NULL;
  71. if (ShellExecuteEx(&ShExecInfo))
  72. {
  73. CloseHandle(ShExecInfo.hProcess);
  74. return true;
  75. }
  76. WriteTextLog(_T("启动进程失败:%d"), GetLastError());
  77. return false;
  78. }
  79. void CloseProcess(LPCTSTR lpProcessName)
  80. {
  81. PROCESSENTRY32 pe32 = { 0 };
  82. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  83. if (hProcessSnap == NULL) return;
  84. // 遍历进程;
  85. pe32.dwSize = sizeof(PROCESSENTRY32);
  86. for (BOOL bRet = Process32First(hProcessSnap, &pe32); bRet; bRet = Process32Next(hProcessSnap, &pe32)) {
  87. if (_tcscmp(lpProcessName, pe32.szExeFile) == 0) {
  88. HANDLE hProc = ::OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
  89. TerminateProcess(hProc, 4);
  90. }
  91. }
  92. CloseHandle(hProcessSnap);
  93. }
  94. // 返回第一个找到的进程pid
  95. DWORD GetProcessId(LPCTSTR lpProcessName)
  96. {
  97. DWORD dwProcessId = 0;
  98. PROCESSENTRY32 pe32 = { 0 };
  99. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  100. if (hProcessSnap == NULL) return 0;
  101. // 遍历进程;
  102. pe32.dwSize = sizeof(PROCESSENTRY32);
  103. for (BOOL bRet = Process32First(hProcessSnap, &pe32); bRet; bRet = Process32Next(hProcessSnap, &pe32)) {
  104. if (_tcscmp(lpProcessName, pe32.szExeFile) == 0) {
  105. dwProcessId = pe32.th32ProcessID;
  106. break;
  107. }
  108. }
  109. CloseHandle(hProcessSnap);
  110. return dwProcessId;
  111. }
  112. void GetAllProcessId(std::vector<DWORD>& vtPid, LPCTSTR lpProcessName)
  113. {
  114. vtPid.clear();
  115. PROCESSENTRY32 pe32 = { 0 };
  116. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  117. if (hProcessSnap == NULL) return;
  118. // 遍历进程;
  119. pe32.dwSize = sizeof(PROCESSENTRY32);
  120. for (BOOL bRet = Process32First(hProcessSnap, &pe32); bRet; bRet = Process32Next(hProcessSnap, &pe32)) {
  121. if (_tcscmp(lpProcessName, pe32.szExeFile) == 0) {
  122. vtPid.push_back(pe32.th32ProcessID);
  123. GetClassNameWnd(pe32.th32ProcessID, _T("Intermediate D3D Window"));
  124. GetWindowNameWnd(pe32.th32ProcessID, _T("Feishu Rooms"));
  125. }
  126. }
  127. CloseHandle(hProcessSnap);
  128. }
  129. HWND GetProcessMainWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetWndName)
  130. {
  131. DWORD dwCurPorcessId = 0;
  132. HWND hTagetProcessWnd = NULL;
  133. TCHAR szWndName[MAX_PATH] = { 0 };
  134. TCHAR szClassName[MAX_PATH] = { 0 };
  135. // 取得第一个窗口句柄;
  136. for (HWND hCurWnd = ::GetTopWindow(NULL); hCurWnd != NULL; hCurWnd = ::GetNextWindow(hCurWnd, GW_HWNDNEXT)) {
  137. // 重置为0;
  138. dwCurPorcessId = 0;
  139. // 通过窗口句柄反查进程pid;
  140. DWORD dwThreadId = ::GetWindowThreadProcessId(hCurWnd, &dwCurPorcessId);
  141. if (dwThreadId != 0) {
  142. // 判断当前进程id是否和目标进程id相同;
  143. if (dwCurPorcessId == dwTagetProcessId) {
  144. if (lpTagetWndName == NULL) {
  145. hTagetProcessWnd = hCurWnd;
  146. break;
  147. }
  148. else {
  149. // 获取窗口名称;
  150. ::GetWindowText(hCurWnd, szWndName, sizeof(szWndName) / sizeof(TCHAR));
  151. // 获取窗口类名;
  152. ::GetClassName(hCurWnd, szClassName, sizeof(szClassName) / sizeof(TCHAR));
  153. #ifdef _DEBUG
  154. TCHAR szLogMsg[MAX_PATH] = { 0 };
  155. _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClassName, szWndName, hCurWnd);
  156. OutputDebugString(szLogMsg);
  157. #endif
  158. if (_tcsstr(szWndName, lpTagetWndName) != NULL) {
  159. hTagetProcessWnd = hCurWnd;
  160. break;
  161. }
  162. }
  163. }
  164. }
  165. }
  166. // 当前窗口有可能不是进程父窗口;
  167. HWND hParentWnd = hTagetProcessWnd;
  168. while (hParentWnd) {
  169. hParentWnd = ::GetParent(hTagetProcessWnd);
  170. if (hParentWnd == NULL)
  171. break;
  172. hTagetProcessWnd = hParentWnd;
  173. }
  174. return hTagetProcessWnd;
  175. }
  176. HWND GetProcessMainWnd(LPCTSTR lpProcessName, LPCTSTR lpTagetWndName)
  177. {
  178. HWND hTagetWnd = NULL;
  179. DWORD dwProcessId = 0;
  180. if ((dwProcessId = GetProcessId(lpProcessName)) != 0) {
  181. hTagetWnd = GetProcessMainWnd(dwProcessId, lpTagetWndName);
  182. }
  183. return hTagetWnd;
  184. }
  185. HWND GetClassNameWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetClassName)
  186. {
  187. DWORD dwCurPorcessId = 0;
  188. HWND hTagetProcessWnd = NULL;
  189. TCHAR szWndName[MAX_PATH] = { 0 };
  190. TCHAR szClassName[MAX_PATH] = { 0 };
  191. // 取得第一个窗口句柄;
  192. for (HWND hCurWnd = ::GetTopWindow(NULL); hCurWnd != NULL; hCurWnd = ::GetNextWindow(hCurWnd, GW_HWNDNEXT)) {
  193. // 重置为0;
  194. dwCurPorcessId = 0;
  195. // 通过窗口句柄反查进程pid;
  196. DWORD dwThreadId = ::GetWindowThreadProcessId(hCurWnd, &dwCurPorcessId);
  197. if (dwThreadId != 0) {
  198. // 判断当前进程id是否和目标进程id相同;
  199. if (dwCurPorcessId == dwTagetProcessId) {
  200. if (lpTagetClassName == NULL) {
  201. hTagetProcessWnd = hCurWnd;
  202. break;
  203. }
  204. else {
  205. // 获取窗口名称;
  206. ::GetWindowText(hCurWnd, szWndName, sizeof(szWndName) / sizeof(TCHAR));
  207. // 获取窗口类名;
  208. ::GetClassName(hCurWnd, szClassName, sizeof(szClassName) / sizeof(TCHAR));
  209. #ifdef _DEBUG
  210. TCHAR szLogMsg[MAX_PATH] = { 0 };
  211. _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClassName, szWndName, hCurWnd);
  212. OutputDebugString(szLogMsg);
  213. #endif
  214. if (_tcsstr(szClassName, lpTagetClassName) != NULL) {
  215. hTagetProcessWnd = hCurWnd;
  216. break;
  217. }
  218. }
  219. }
  220. }
  221. }
  222. return hTagetProcessWnd;
  223. }
  224. HWND GetWindowNameWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetWindowName)
  225. {
  226. DWORD dwCurPorcessId = 0;
  227. HWND hTagetProcessWnd = NULL;
  228. TCHAR szWndName[MAX_PATH] = { 0 };
  229. TCHAR szClassName[MAX_PATH] = { 0 };
  230. // 取得第一个窗口句柄;
  231. for (HWND hCurWnd = ::GetTopWindow(NULL); hCurWnd != NULL; hCurWnd = ::GetNextWindow(hCurWnd, GW_HWNDNEXT)) {
  232. // 重置为0;
  233. dwCurPorcessId = 0;
  234. // 通过窗口句柄反查进程pid;
  235. DWORD dwThreadId = ::GetWindowThreadProcessId(hCurWnd, &dwCurPorcessId);
  236. if (dwThreadId != 0) {
  237. // 判断当前进程id是否和目标进程id相同;
  238. if (dwCurPorcessId == dwTagetProcessId) {
  239. if (lpTagetWindowName == NULL) {
  240. hTagetProcessWnd = hCurWnd;
  241. break;
  242. }
  243. else {
  244. // 获取窗口名称;
  245. ::GetWindowText(hCurWnd, szWndName, sizeof(szWndName) / sizeof(TCHAR));
  246. // 获取窗口类名;
  247. ::GetClassName(hCurWnd, szClassName, sizeof(szClassName) / sizeof(TCHAR));
  248. #ifdef _DEBUG
  249. TCHAR szLogMsg[MAX_PATH] = { 0 };
  250. _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClassName, szWndName, hCurWnd);
  251. OutputDebugString(szLogMsg);
  252. #endif
  253. if (_tcsstr(szWndName, lpTagetWindowName) != NULL) {
  254. hTagetProcessWnd = hCurWnd;
  255. break;
  256. }
  257. }
  258. }
  259. }
  260. }
  261. return hTagetProcessWnd;
  262. }
  263. HWND GetWindowNameWnd(LPCTSTR lpProcessName, LPCTSTR lpTagetWindowName)
  264. {
  265. HWND hTagWnd = NULL;
  266. PROCESSENTRY32 pe32 = { 0 };
  267. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  268. if (hProcessSnap == NULL) return NULL;
  269. // 遍历进程;
  270. pe32.dwSize = sizeof(PROCESSENTRY32);
  271. for (BOOL bRet = Process32First(hProcessSnap, &pe32); bRet; bRet = Process32Next(hProcessSnap, &pe32)) {
  272. if (_tcscmp(lpProcessName, pe32.szExeFile) == 0) {
  273. hTagWnd = GetWindowNameWnd(pe32.th32ProcessID, lpTagetWindowName);
  274. if (hTagWnd != NULL)
  275. break;
  276. }
  277. }
  278. CloseHandle(hProcessSnap);
  279. return hTagWnd;
  280. }
  281. void WriteTextLog(const TCHAR* format, ...)
  282. {
  283. AutoThreadSection aSection(&g_csTextLog);
  284. // 获取今年年份;
  285. __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
  286. struct tm gmtm = { 0 };
  287. localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
  288. // 解析出日志路径;
  289. TCHAR szlogpath[MAX_PATH] = { 0 };
  290. _stprintf_s(szlogpath, _T("%s\\%04d-%02d-%02d.txt"), g_szCurModuleDir, gmtm.tm_year + 1900, gmtm.tm_mon + 1, gmtm.tm_mday);
  291. // 打开或创建文件;
  292. FILE* fp = NULL;
  293. if (_taccess(szlogpath, 0) != -1)
  294. {// 存在;
  295. if (0 == _tfopen_s(&fp, szlogpath, _T("a+")))
  296. // 移动到末尾;
  297. fseek(fp, 0, SEEK_END);
  298. }
  299. else
  300. {// 不存在;
  301. _tfopen_s(&fp, szlogpath, _T("w+"));
  302. }
  303. if (fp == NULL)
  304. return;
  305. // 格式化前设置语言区域;
  306. TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
  307. _tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
  308. // 格式化日志内容;
  309. va_list args = NULL;
  310. int len = 0;
  311. TCHAR* buffer = NULL;
  312. va_start(args, format);
  313. // _vscprintf doesn't count. terminating '\0'
  314. len = _vsctprintf(format, args) + 1;
  315. buffer = (TCHAR*)malloc(len * sizeof(TCHAR));
  316. _vstprintf_s(buffer, len, format, args);
  317. // 将日志内容输入到文件中;
  318. _ftprintf(fp, _T("%04d-%02d-%02d %02d:%02d:%02d %s\n"), gmtm.tm_year + 1900, gmtm.tm_mon + 1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec, buffer);
  319. // 关闭文件,释放资源并设置回原语言区域;
  320. free(buffer);
  321. fclose(fp);
  322. _tsetlocale(LC_CTYPE, old_locale);
  323. free(old_locale);//还原区域设定;
  324. }
  325. };