枚举窗口( ) 找不到一些顶级窗口?

EnumWindows( ) doesn't find some top level windows?

本文关键字:窗口 找不到 枚举      更新时间:2023-10-16

我正在尝试创建一个功能类似于任务管理器的程序以及许多其他功能。目前,我无法使用当前的枚举函数找到所有顶级窗口。出于某种原因,它为某些应用程序正确枚举并填写了 HWND(例如谷歌浏览器、命令提示符、代码::块),但不适用于某些游戏(例如 Roblox(我测试过的一个))。我试图看看 FindWindow() 是否也会失败,但它在这种情况下工作正常。这意味着 EnumWindows() 显然应该找到它,但显然我要么做错了什么,要么我在文档中读错了什么。我真的不想使用FindWindow(),因为我可能不知道大多数窗口的标题。

枚举函数:

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_namet=t%sn"
               "node.process_idtt=t%dn"
               "nCan terminate process : %snn"
               "node.window_handlet=t0x%pn"
               "node.nexttt=t%sn",
               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_namet=t%sn"
            "node.process_idtt=t%dn"
            "nCan terminate process : %snn"
            "node.window_handlet=t0x%pn"
            "node.nexttt=t%sn",
            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!nn");
    print_node( target_process );
    timer( TIMER_STOP, &program_run_time );
    printf( "nnt--tProgram run time : %d millisecondst--tnn", ( int )timer( TIMER_GETDIFF, &program_run_time ) );
    free( target_process->process_name );
    free( target_process );
    return 0;
}

如果你能在 Spy++ 中看到它,你应该能够用 EnumWindows 来理解它。

但是,如果您的查询特定于 ROBLOX,并且您想要的只是窗口句柄,您可以这样做

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

然后你可以像这样得到主句柄:

rbxProc.MainWindowHandle