Вопрос Как получить текст окна по запущенному *.exe? - (Решено)

Krinkels

Он где то тут
Администратор
Могу предложить такой вариант, но он на плюсах:
C++:
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>

int main( void )
{
    int i = 0;
    HANDLE hSnapshot;
    HWND H = FindWindow( NULL, "" );
    char Pch[ 128 ];

    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if( hSnapshot == INVALID_HANDLE_VALUE )
    {
        printf( "Error CreateToolhelp32Snapshot\n" );
        return 0;
    }

    do
    {
        if( IsWindow( H ) ) // Проверим полученный хендл
        {
            if( IsWindowVisible( H ) )
            {
                if( GetWindowText( H, Pch, sizeof( Pch ) ) != NULL )
                {
                    // Пытаемся найти родителя этого окна,
                    // Если он NULL то значит оно главное
                    if( GetWindow( H, GW_OWNER ) == NULL )
                    {
                        //Выводим названия окон
                        printf( "%s\n", Pch );                       
                    }
                }
            }
        }
        H = GetNextWindow( H, GW_HWNDNEXT );
    }
    while( H != NULL );

    CloseHandle( hSnapshot );
    CloseHandle( H );

    return 0;
}
 

Хамик

Старожил
@Krinkels, спасибо, но в плюсах не шарю. Подождем, может кто сможет портировать в inno'ский код.
 

DiCaPrIo

Новичок
code_language.pascal:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "My Program"
#define MyAppVersion "1.5"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{098CECEE-B4D4-4A44-B288-71DDE64F7055}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

[code]
function EnumWindows(lpEnumFunc: Longword; lParam: Longword): Boolean; external 'EnumWindows@user32.dll stdcall';
function GetWindowText(hWnd: HWND; lpString: String; nMaxCount: Integer): Integer;external 'GetWindowTextW@user32.dll stdcall';
function GetWindowTextLength(hWnd: HWND): Integer;external 'GetWindowTextLengthW@user32.dll stdcall';
function GetWindowThreadProcessId(hWnd: HWND; var dwProcessId: DWORD): DWORD;external 'GetWindowThreadProcessId@user32.dll stdcall';
function GetCurrentProcessId: DWORD;external 'GetCurrentProcessId@kernel32.dll stdcall';
function IsWindowVisible(hWnd: HWND): BOOL; external 'IsWindowVisible@user32.dll stdcall';

function GetProcessPID(Exe: String):DWORD;
var
  WbemLocator : Variant;WMIService   : Variant;WbemObjectSet: Variant;WbemObject   : Variant;
begin;
  WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  WMIService := WbemLocator.ConnectServer('localhost', 'root\CIMV2');
  WbemObjectSet := WMIService.ExecQuery('SELECT * FROM Win32_Process Where Name="' + Exe+ '"');
  WbemObject := WbemObjectSet.ItemIndex(0);
  Result:=WbemObject.ProcessId;
  WbemObject := Unassigned;
end;

Procedure GetWinText(var Caption:String); forward;
function EnumWindowsProc(h: HWND;ID: Cardinal): Boolean;
var S:String;pid:DWORD;
begin
  GetWindowThreadProcessId(h,pid);
  Setlength(S,GetWindowTextLength(h)+1)
  GetWindowText(h, S, GetWindowTextLength(h)+1);
  S := Trim(S);
  if (ID = pid) then
  if  S<>'' then
    GetWinText(S);
  Result := True;
end;

Procedure GetExeCaption(ExeName:String);
begin
  EnumWindows(CallbackAddr('EnumWindowsProc'), Longword(GetProcessPID(ExeName)));
end;

Procedure GetWinText(var Caption:String);
begin
    MsgBox(Caption ,mbinformation,0);
end;

procedure InitializeWizard(); var pid:DWORD;
begin
GetExeCaption('setup.tmp');
end;
 
Последнее редактирование:

Хамик

Старожил
@DiCaPrIo, пример рабочий, но есть пару нюансов:
1. если процесс не найден, то ошибка на строке WbemObject := WbemObjectSet.ItemIndex(0); пишет не правильный параметр.
2. текст окна получает, но еще и глубже сканирует процесс, всякие там Default IME выводит.
За пример спасибо, попробую под себя настроить.
 

DiCaPrIo

Новичок
code_language.pascal:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "My Program"
#define MyAppVersion "1.5"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{098CECEE-B4D4-4A44-B288-71DDE64F7055}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

[code]
function EnumWindows(lpEnumFunc: Longword; lParam: Longword): Boolean; external 'EnumWindows@user32.dll stdcall';
function GetWindowText(hWnd: HWND; lpString: String; nMaxCount: Integer): Integer;external 'GetWindowTextW@user32.dll stdcall';
function GetWindowTextLength(hWnd: HWND): Integer;external 'GetWindowTextLengthW@user32.dll stdcall';
function GetWindowThreadProcessId(hWnd: HWND; var dwProcessId: DWORD): DWORD;external 'GetWindowThreadProcessId@user32.dll stdcall';
function GetCurrentProcessId: DWORD;external 'GetCurrentProcessId@kernel32.dll stdcall';
function GetTopWindow(hWnd: HWND): BOOL; external 'GetTopWindow@user32.dll stdcall';
function IsWindowVisible(hWnd: HWND): BOOL; external 'IsWindowVisible@user32.dll stdcall';

function GetProcessID(AppName: String):DWORD;
var
  WbemLocator : Variant;WMIService   : Variant;WbemObjectSet: Variant;WbemObject   : Variant;
begin;
  WbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  WMIService := WbemLocator.ConnectServer('localhost', 'root\CIMV2');
  WbemObjectSet := WMIService.ExecQuery('SELECT * FROM Win32_Process Where Name="' + AppName + '"');
  if (WbemObjectSet.Count - 1 <> -1) then  begin
  WbemObject := WbemObjectSet.ItemIndex(0);
  Result:=WbemObject.ProcessId;
  end;
  WbemLocator:= Unassigned;
  WMIService:=Unassigned;
  WbemObject := Unassigned;
end;

Procedure GetWinText(var Caption:String); forward;
function EnumWindowsProc(h: HWND;ID: Cardinal): Boolean;
var S:String;pid:DWORD;
begin
  GetWindowThreadProcessId(h,pid);
  Setlength(S,GetWindowTextLength(h)+1)
  GetWindowText(h, S, GetWindowTextLength(h)+1);
  S := Trim(S);
  if (ID = pid) then
  if IsWindowVisible(h) or GetTopWindow(h) then
  if  S<>'' then
    GetWinText(S);
  Result := True;
end;

Procedure GetExeCaption(ExeName:String);
begin
  EnumWindows(CallbackAddr('EnumWindowsProc'), Longword(GetProcessID(ExeName)));
end;

Procedure GetWinText(var Caption:String);
begin
    MsgBox(Caption ,mbinformation,0);
end;

procedure InitializeWizard(); var pid:DWORD;
begin
GetExeCaption('setup.tmp');
end;
 
Сверху