How to get file path of a window handle?

Please discuss general Delphi programming topics here.

How to get file path of a window handle?

Postby Sina » August 29th, 2005, 8:54 am

HI
please help me
I want to get file path of a window handle
i don't want to use any library
I use GetModuleFileName function but i could just get my own program path
thank u
bye
User avatar
Sina
Junior Member
Junior Member
 
Posts: 32
Joined: August 29th, 2005, 8:33 am
Location: United States

Postby Kambiz » August 29th, 2005, 4:46 pm

I use the following unit in my applications to show version information to the user.

Code: Select all
//------------------------------------------------------------------------------
//
// AppInfo.pas -- Gathers Application's Version Information
//
// Copyright (C) Kambiz R. Khojasteh
// kambiz@qualilife.com
//
//------------------------------------------------------------------------------


unit AppInfo;

interface

uses
  Windows, Classes;

// :: Returns the full version information of the operating system
function GetOperatingSystemVersion: String;

// :: Returns the value of version iformation specified by ValueName parameter
//    from the file specified by the FileName parameter.
function GetVersionInfo(const FileName, ValueName: String): String;

// :: Fills the strings specified by Modules parameterwith the path of modules
//    loaded by the process specified by the ProcessID parameter.
// :: Returns the number of modules used by the process.
// :: Returns -1 on failure.
function GetModulesFromProcessID(ProcessID: THandle; Modules: TStrings): Integer;

// :: Fills the strings specified by Modules parameter with the path of modules
//    loaded by the process of the window specified by the hWnd parameter.
// :: Returns the number of modules used by the process.
// :: Returns -1 on failure.
function GetModulesFromWindowHandle(hWND: HWND; Modules: TStrings): Integer;

// :: Formats output of either GetModulesFromProcessID or GetModulesFromWindowHandle
//    procedures. This procedue includes version number of the modules to the list.
//    Mouldes and FormattedModules can point to same variable.
procedure FormatModuleList(Modules, FormattedModules: TStrings);

implementation

uses
  PSAPI, SysUtils;

function GetOperatingSystemVersion: String;
begin
  if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and (Win32MajorVersion = 4) then
  begin
    if (Win32MinorVersion = 90) and (Win32BuildNumber = 3000) then
      Result := 'Windows Me'
    else if (Win32MinorVersion = 1) and (Win32BuildNumber = 2222) then
      Result := 'Windows 98 SE'
    else if Win32MinorVersion = 0 then
      Result := 'Windows 95 ' + Win32CSDVersion
    else
      Result := Format('Windows %d.%d (Build %d) %s', [Win32MajorVersion,
        Win32MinorVersion, Win32BuildNumber, Win32CSDVersion]);
  end
  else if Win32Platform = VER_PLATFORM_WIN32_NT then
  begin
    if (Win32MajorVersion = 5) and (Win32MinorVersion = 0) then
      Result := Format('Windows 2000 (Build %d) %s', [Win32BuildNumber, Win32CSDVersion])
    else if (Win32MajorVersion = 5) and (Win32MinorVersion = 1) then
      Result := Format('Windows XP (Build %d) %s', [Win32BuildNumber, Win32CSDVersion])
    else
      Result := Format('Windows NT %d.%d (Build %d) %s', [Win32MajorVersion,
        Win32MinorVersion, Win32BuildNumber, Win32CSDVersion]);
  end
  else
    Result := Format('Windows %d.%d (Build %d) %s', [Win32MajorVersion,
      Win32MinorVersion, Win32BuildNumber, Win32CSDVersion]);
end;

function GetVersionInfo(const FileName, ValueName: String): String;
var
  Trans: PDWORD;
  VerInfoSize, ValSize, Dummy: DWORD;
  VerInfo, Value: Pointer;
  TransStr, InfoStr: String;
begin
  Result := '';
  VerInfoSize := GetFileVersioninfoSize(PChar(FileName), Dummy);
  if VerInfoSize <> 0 then
  begin
    GetMem(VerInfo, VerInfoSize);
    try
      if GetFileVersionInfo(PChar(FileName), Dummy, VerInfoSize, VerInfo) then
      begin
        VerQueryValue(VerInfo, '\VarFileInfo\Translation', Pointer(Trans), valSize);
        TransStr := IntToHex(LoWord(Trans^), 4) + IntToHex(HiWord(Trans^), 4);
        if CompareText(ValueName, 'Language') <> 0 then
        begin
          InfoStr := '\StringFileInfo\' + TransStr + '\' + ValueName;
          if VerQueryValue(VerInfo, PChar(InfoStr), Value, ValSize) then
            Result := StrPas(Value);
        end
        else
        begin
          SetLength(Result, 256);
          VerLanguageName(LoWord(Trans^), PChar(Result), 256);
          SetLength(Result, StrLen(PChar(Result)));
        end;
      end;
    finally
      FreeMem(VerInfo);
    end;
  end;
end;

function GetModulesFromProcessID(ProcessID: THandle; Modules: TStrings): Integer;
var
  hProcess: THandle;
  NeededBytes: DWORD;
  phModules, phModule: PDWORD;
  ModuleName: array[0..1024] of Char;
  I: DWORD;
begin
  Result := -1;
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
  if hProcess <> 0 then
  begin
    try
      Result := 0;
      phModules := nil;
      if EnumProcessModules(hProcess, phModules, 0, NeededBytes) then
      begin
        GetMem(phModules, NeededBytes);
        try
          if EnumProcessModules(hProcess, phModules, NeededBytes, NeededBytes) then
          begin
            Result := NeededBytes div SizeOf(THandle);
            if Modules <> nil then
            begin
              phModule := phModules;
              Modules.BeginUpdate;
              try
                for I := 0 to Result - 1 do
                begin
                  if GetModuleFileNameEx(hProcess, phModule^, @ModuleName, SizeOf(ModuleName)) > 0 then
                    Modules.Add(ModuleName);
                  Inc(phModule);
                end;
              finally
                Modules.EndUpdate;
              end;
            end;
          end;
        finally
          FreeMem(phModules);
        end;
      end;
    finally
      CloseHandle(hProcess);
    end;
  end;
end;

function GetModulesFromWindowHandle(hWND: HWND; Modules: TStrings): Integer;
var
  ProcessID: THandle;
begin
  if GetWindowThreadProcessId(hWND, ProcessID) <> 0 then
    Result := GetModulesFromProcessID(ProcessID, Modules)
  else
    Result := -1;
end;

procedure FormatModuleList(Modules, FormattedModules: TStrings);
var
  I, N: Integer;
  MaxFileNameLen: Integer;
  MaxVersionLen: Integer;
  FileName: String;
  FilePath: String;
  Version: String;
  Line: String;
begin
  FormattedModules.BeginUpdate;
  try
    MaxFileNameLen := 0;
    MaxVersionLen := 0;
    for I := 0 to Modules.Count - 1 do
    begin
       FileName := ExtractFileName(Modules[I]);
       FilePath := ExcludeTrailingPathDelimiter(ExtractFilePath(Modules[I]));
       Version := GetVersionInfo(Modules[I], 'FileVersion');
        if Length(FileName) > MaxFileNameLen then
          MaxFileNameLen := Length(FileName);
        if Length(Version) > MaxVersionLen then
          MaxVersionLen := Length(Version);
        Line := FileName + #1 + Version + #1 + FilePath;
       if I < FormattedModules.Count then
         FormattedModules[I] := Line
       else
         FormattedModules.Add(Line);
    end;
    for I := FormattedModules.Count - 1 downto Modules.Count do
      FormattedModules.Delete(I);
    for I := 0 to FormattedModules.Count - 1 do
    begin
      Line := FormattedModules[I];
      N := Pos(#1, Line);
      Line := StringReplace(Line, #1, StringOfChar(' ', MaxFileNameLen + 2 - N) + ^I, []);
      N := Pos(#1, Line);
      Line := StringReplace(Line, #1, StringOfChar(' ', MaxFileNameLen + 2 + MaxVersionLen + 2 - N) + ^I, []);
      FormattedModules[I] := Line;
    end;
  finally
    FormattedModules.EndUpdate;
  end;
end;

end.

As an exmaple:

Code: Select all
uses
  AppInfo;

procedure TForm1.FormCreate(Sender: TObject);
begin
  GetModulesFromWindowHandle(Handle, ListBox1.Items);
  FormatModuleList(ListBox1.Items, Memo1.Lines);
  Caption := GetOperatingSystemVersion;
end;

If the specified ProcessID or Window Handle belongs to an application, the first item in the list is the application's path, otherwise it's the library path.

Cheers
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2424
Joined: March 7th, 2003, 7:10 pm

Thank u

Postby Sina » August 30th, 2005, 8:29 am

Thanks a lot
User avatar
Sina
Junior Member
Junior Member
 
Posts: 32
Joined: August 29th, 2005, 8:33 am
Location: United States


Return to Delphi Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron