다른 많은 기능과 함께 작업 관리자와 비슷한 기능을하는 프로그램을 만들려고합니다. 현재 현재 열거 함수를 사용하여 모든 최상위 창을 찾는 데 문제가 있습니다. 어떤 이유로 인해 일부 애플리케이션 (예 : Chrome, 명령 프롬프트, 코드 :: 블록)에서 HWND를 올바르게 열거하고 채 웁니다 (예 : Roblox (테스트 한 건 하나)). 어쩌면 FindWindow()도 실패할지 알기 위해 노력했지만, 그 맥락에서 잘 동작했습니다. 즉, EnumWindows()가 분명히 찾아야하지만 분명히 잘못된 것이거나 문서에서 잘못된 것을 읽은 것입니다. 나는 FindWindow()를 사용하지 않아도된다. 어쨌든 대부분의 윈도우 제목을 알지 못할 것이다.EnumWindows()가 최상위 창을 찾지 못합니까?
열거 기능 :
BOOL CALLBACK FindWindows(HWND handle, LPARAM option)
{
DWORD window_process_id = 0;
GetWindowThreadProcessId(handle, &window_process_id);
process_list * p1 = NULL;
switch (option)
{
case FIND_WINDOW_HANDLE :
if (IsWindowEnabled(handle))
for (p1 = head_copy; p1; p1 = p1->next)
if (p1->pid == window_process_id)
p1->window_handle = handle;
break;
default :
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
break;
}
return TRUE;
}
전체 소스 : 당신이 스파이에서 볼 수있는 경우
/* Preprocessor directives */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#define TARGET_PROCESS "chrome.exe"
/* Structures */
typedef struct process_list
{
char * process_name;
DWORD pid;
HANDLE process_handle;
HWND window_handle;
int process_name_sz;
struct process_list * next;
} process_list;
typedef struct drawing_data
{
RECT window_pos;
} drawing_data;
/* Enums (Global integer constants) */
enum
{
FIND_WINDOW_HANDLE
};
enum
{
TIMER_START,
TIMER_STOP,
TIMER_GETDIFF
};
typedef struct t_timer
{
clock_t start_time;
clock_t end_time;
} t_timer;
/* Global variables */
process_list * head_copy = NULL;
/* ***************************************************************** */
/* Time functions */
clock_t timer(int command, t_timer * timer1)
{
switch (command)
{
case TIMER_START :
timer1->start_time = clock();
break;
case TIMER_STOP :
timer1->end_time = clock();
break;
case TIMER_GETDIFF :
return ((timer1->end_time - timer1->start_time)/(CLOCKS_PER_SEC/1000));
break;
default : break;
}
return -1;
}
/* ***************************************************************** */
/* Windows error functions */
void show_error(char * user_string, BOOL exit)
{
char buffer[BUFSIZ] = { 0 };
DWORD error_code = GetLastError();
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buffer,
BUFSIZ,
NULL
);
printf("%s : %s", user_string, buffer);
if (exit) ExitProcess(error_code);
return;
}
/* ***************************************************************** */
void win_error(char * message, BOOL exit)
{
char buffer[BUFSIZ] = { 0 };
DWORD error_code = GetLastError();
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buffer,
BUFSIZ,
NULL
);
MessageBox(NULL, buffer, "Error from System :", MB_ICONWARNING | MB_OK);
if (exit) ExitProcess(error_code);
return;
}
/* ***************************************************************** */
/* Linked list functions */
process_list * create()
{
process_list * temp = NULL;
if (!(temp = malloc(sizeof(process_list))))
{
perror("Malloc");
exit(1);
}
return temp;
}
/* ***************************************************************** */
process_list * add(process_list * head, HANDLE process_handle, PROCESSENTRY32 * process_structure)
{
process_list * temp = NULL;
if (!head)
{
head = create();
head->pid = process_structure->th32ParentProcessID;
head->process_handle = process_handle;
head->process_name_sz = strlen(process_structure->szExeFile) + 1;
head->process_name = malloc(head->process_name_sz);
if (!head->process_name)
{
perror("Malloc");
exit(1);
}
strcpy(head->process_name, process_structure->szExeFile);
head->next = NULL;
} else
{
temp = create();
temp->next = head;
head = temp;
head->pid = process_structure->th32ParentProcessID;
head->process_handle = process_handle;
head->process_name_sz = strlen(process_structure->szExeFile) + 1;
head->process_name = malloc(head->process_name_sz);
if (!head->process_name)
{
perror("Malloc");
exit(1);
}
strcpy(head->process_name, process_structure->szExeFile);
}
return head;
}
/* ***************************************************************** */
void print_list(process_list * head)
{
process_list * p1 = NULL;
for (p1 = head; p1; p1 = p1->next )
{
printf(
"-------------------------------------------------\n"
"node.process_name\t=\t%s\n"
"node.process_id\t\t=\t%d\n"
"\nCan terminate process : %s\n\n"
"node.window_handle\t=\t0x%p\n"
"node.next\t\t=\t%s\n",
p1->process_name,
(int)p1->pid,
p1->process_handle == INVALID_HANDLE_VALUE ? "NO" : "YES",
(void *)p1->window_handle,
p1->next ? "(node address)\n" : "NULL"
);
}
}
/* ***************************************************************** */
void print_node(process_list * node)
{
printf(
"node.process_name\t=\t%s\n"
"node.process_id\t\t=\t%d\n"
"\nCan terminate process : %s\n\n"
"node.window_handle\t=\t0x%p\n"
"node.next\t\t=\t%s\n",
node->process_name,
(int)node->pid,
node->process_handle == INVALID_HANDLE_VALUE ? "NO" : "YES",
(void *)node->window_handle,
node->next ? "(node address)\n" : "NULL"
);
return;
}
/* ***************************************************************** */
process_list * delete(process_list * head, process_list * node)
{
process_list * p1 = head;
process_list * p2 = NULL;
if (!p1)
return NULL;
else if (p1 == node)
{
if (!p1->next)
{
free(p1->process_name);
if (p1->process_handle != INVALID_HANDLE_VALUE)
CloseHandle(p1->process_handle);
if (p1->window_handle)
CloseHandle(p1->window_handle);
free(p1);
}
else
{
free(p1->process_name);
if (p1->process_handle != INVALID_HANDLE_VALUE)
CloseHandle(p1->process_handle);
if (p1->window_handle)
CloseHandle(p1->window_handle);
p2 = head->next;
free(p1);
return p2;
}
return NULL;
}
for (; p1 && p1 != node; p2 = p1, p1 = p1->next);
if (!p1)
return NULL;
else
{
free(p1->process_name);
if (p1->process_handle != INVALID_HANDLE_VALUE)
CloseHandle(p1->process_handle);
if (p1->window_handle)
CloseHandle(p1->window_handle);
p2->next = p1->next;
free(p1);
}
return head;
}
/* ***************************************************************** */
void free_list(process_list * head)
{
process_list * p1 = head;
process_list * p2 = NULL;
while (p1)
{
free( p1->process_name);
if (p1->process_handle != INVALID_HANDLE_VALUE)
CloseHandle(p1->process_handle);
if (p1->window_handle)
CloseHandle(p1->window_handle);
p2 = p1;
p1 = p1->next;
free(p2);
}
return;
}
/* ***************************************************************** */
process_list * find_process_and_copy_node(process_list * head, const char * process_name)
{
BOOL is_match = FALSE;
process_list * p1 = NULL;
process_list * new_node = NULL;
for (p1 = head; p1; p1 = p1->next)
{
if (!strcmp(p1->process_name, process_name))
{
is_match = TRUE;
break;
}
}
if (is_match)
{
new_node = create();
new_node->pid = p1->pid;
new_node->process_handle = p1->process_handle;
if (!(new_node->process_name = malloc(p1->process_name_sz)))
{
perror("Malloc");
free(new_node);
free_list(head);
exit(1);
}
new_node->process_name = strcpy(new_node->process_name, p1->process_name);
new_node->process_name_sz = p1->process_name_sz;
new_node->window_handle = p1->window_handle;
new_node->next = NULL;
return new_node;
}
else return NULL;
}
/* ***************************************************************** */
/* WinAPI functions */
BOOL CALLBACK FindWindows(HWND handle, LPARAM option)
{
DWORD window_process_id = 0;
GetWindowThreadProcessId(handle, &window_process_id);
process_list * p1 = NULL;
switch (option)
{
case FIND_WINDOW_HANDLE :
if (IsWindowEnabled(handle))
for (p1 = head_copy; p1; p1 = p1->next)
if (p1->pid == window_process_id)
p1->window_handle = handle;
break;
default :
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
break;
}
return TRUE;
}
/* ***************************************************************** */
process_list * get_process_list(process_list * head)
{
HANDLE h_process_snap;
HANDLE h_process;
PROCESSENTRY32 process_structure;
h_process_snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(h_process_snap == INVALID_HANDLE_VALUE)
{
show_error("CreateToolhelp32Snapshot", FALSE);
return NULL;
}
process_structure.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(h_process_snap, &process_structure))
{
show_error("Process32First", FALSE);
CloseHandle(h_process_snap);
return NULL;
}
do
{
h_process = OpenProcess(PROCESS_TERMINATE, FALSE, process_structure.th32ProcessID);
if (h_process)
head = add(head, h_process, &process_structure);
else
head = add(head, INVALID_HANDLE_VALUE, &process_structure);
} while(Process32Next(h_process_snap, &process_structure));
CloseHandle(h_process_snap);
return head;
}
/* ***************************************************************** */
process_list * find_process(const char * process_name)
{
process_list * head = NULL;
process_list * target_process = NULL;
if (!(head = get_process_list(head)))
exit(1);
head_copy = head;
if (!EnumWindows(FindWindows, FIND_WINDOW_HANDLE))
win_error("EnumWindows", FALSE);
target_process = find_process_and_copy_node(head, TARGET_PROCESS);
free_list(head);
return target_process;
}
/* ***************************************************************** */
int main()
{
t_timer program_run_time;
memset(&program_run_time, 0, sizeof(t_timer));
timer(TIMER_START, &program_run_time);
process_list * target_process = NULL;
printf("Searching for target process...\n");
while (!(target_process = find_process(TARGET_PROCESS)))
Sleep(100);
printf("Found!\n\n");
print_node(target_process);
timer(TIMER_STOP, &program_run_time);
printf("\n\n\t--\tProgram run time : %d milliseconds\t--\t\n\n", (int)timer(TIMER_GETDIFF, &program_run_time));
free(target_process->process_name);
free(target_process);
return 0;
}
당신은 것을 잘못된 ID를'process_list :: pid'에 저장하려고합니다. 아마도'th32ParentProcessID'가 아닌'PROCESSENTRY32 :: th32ProcessID'를 원할 것입니다. –
많은 관련성없는 코드가 있습니다. 동일한 문제를 재현하는 최소한의 [SSCCE] (http://sscce.org)로 줄이십시오. Igor이 말했던 것 외에도 콜백은 프로세스가 여러 개의 최상위 창을 가질 수 있다는 것을 고려하지 않았습니다. 콜백이 실제로 의도 한 창을 찾지 못하면 Spy ++ 또는 유사한 도구를 사용하여 창이 실제로 최상위 수준인지 확인하십시오. 최상위 창처럼 보이는 창 *이 실제로 * 최상위 창임을 보장하지는 않습니다. –
내 문제가 해결되었습니다. 또한 문제가되는 코드를 지적하려고했지만 실제로 다음 번에 더 작은 프로그램으로 축소해야합니다. – TheDelightfulEnd