2013-10-22 4 views
1

다른 많은 기능과 함께 작업 관리자와 비슷한 기능을하는 프로그램을 만들려고합니다. 현재 현재 열거 함수를 사용하여 모든 최상위 창을 찾는 데 문제가 있습니다. 어떤 이유로 인해 일부 애플리케이션 (예 : 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; 
} 
+1

당신은 것을 잘못된 ID를'process_list :: pid'에 저장하려고합니다. 아마도'th32ParentProcessID'가 아닌'PROCESSENTRY32 :: th32ProcessID'를 원할 것입니다. –

+2

많은 관련성없는 코드가 있습니다. 동일한 문제를 재현하는 최소한의 [SSCCE] (http://sscce.org)로 줄이십시오. Igor이 말했던 것 외에도 콜백은 프로세스가 여러 개의 최상위 창을 가질 수 있다는 것을 고려하지 않았습니다. 콜백이 실제로 의도 한 창을 찾지 못하면 Spy ++ 또는 유사한 도구를 사용하여 창이 실제로 최상위 수준인지 확인하십시오. 최상위 창처럼 보이는 창 *이 실제로 * 최상위 창임을 보장하지는 않습니다. –

+0

내 문제가 해결되었습니다. 또한 문제가되는 코드를 지적하려고했지만 실제로 다음 번에 더 작은 프로그램으로 축소해야합니다. – TheDelightfulEnd

답변

-3

++, 당신은 EnumWindows로 얻을 수 있어야합니다.

하지만 당신의 쿼리가 ROBLOX 별과 당신이 원하는 모든 창 핸들 경우, 당신은

foreach (Process p in Process.GetProcesses()) 
     { 
      if (p.MainWindowTitle == "Roblox - [Place1]") 
      { 
       rbxProc = p; 
       Console.WriteLine("FOUND ROBLOX Process"); 
      } 
     } 

을 할 수 있으며, 다음과 같은 주요 핸들을 얻을 수 있습니다 :

rbxProc.MainWindowHandle 
+0

불쾌하지 않아도 C/C++와 C#을 혼동 했습니까? 이 질문은이 문맥에서 부적절하고 부적절한 상위 레벨 코드로 명확하게 작성되었습니다. 정말로 작성한 코드에는 좋은 번역이 없으며, 일반 Win32 코드에는 MainWindowHandle이 없습니다. – TheDelightfulEnd

+0

winapi는 모든 언어에서 동일하며, 내가 쌓아 놓은 코드입니다. –

관련 문제