Search code examples
windowsdelphilazarus

How to get path of current active application window?


I want to get the path to the executable file of the current active Window.

I tried:

var
  WindowModuleFileName : array[0..100] of Char;  
  sourceWindow: Hwnd;      
begin
  sourceWindow := GetActiveWindow;
  GetWindowModuleFileName(sourceWindow, PChar(WindowModuleFileName), sizeof(WindowModuleFileName));    
  ShowMessage(WindowModuleFileName);    
end;

But it returned correct answer only when my application window was active. What am I doing wrong?


Solution

  • You can't use GetWindowModuleFileName to locate files for other processes than your own, as stated on GetModuleFileName MSDN:

    Retrieves the fully-qualified path for the file that contains the specified module. The module must have been loaded by the current process.

    To locate the file for a module that was loaded by another process, use the GetModuleFileNameEx function.

    Therefore, you have to use GetModuleFileNameEx combined with GetWindowThreadProcessId/GetForegroundWindow. This will return you what you need:

    uses
      Winapi.Windows, Winapi.PsAPI, System.SysUtils;
    
    function GetCurrentActiveProcessPath: String;
    var
      pid     : DWORD;
      hProcess: THandle;
      path    : array[0..4095] of Char;
    begin
      GetWindowThreadProcessId(GetForegroundWindow, pid);
    
      hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, pid);
      if hProcess <> 0 then
        try
          if GetModuleFileNameEx(hProcess, 0, @path[0], Length(path)) = 0 then
            RaiseLastOSError;
    
          result := path;
        finally
          CloseHandle(hProcess);
        end
      else
        RaiseLastOSError;
    end;