2014-02-25 60 views
0

我想获取当前活动窗口的可执行文件的路径。如何获取当前活动应用程序窗口的路径?

我想:

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

但它返回正确的答案,只有当我的应用程序窗口都是无效的。 我在做什么错?

回答

4

不能使用GetWindowModuleFileName来定位文件不是您自己的过程,在GetModuleFileName MSDN如说:

获取完全合格的路径包含指定的模块文件。该模块必须已由当前进程加载。

要找到由另一个进程加载的模块的文件, 使用GetModuleFileNameEx函数。

因此,你必须使用GetModuleFileNameExGetWindowThreadProcessId/GetForegroundWindow结合。这将返回你所需要的:

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; 
+0

想必'GetWindowModuleFileName()'是自1定制包装器)它不是一个API函数,和2),它被传递一个'HWND'作为参数。 'GetModuleFileName/Ex()'代替'HMODULE'。顺便说一句,还有['GetProcessImageFileName()'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms683217.aspx)和['QueryFullProcessImageName()'](http:// msdn.microsoft.com/en-us/library/windows/desktop/ms684919.aspx)可用的API函数。他们不需要'PROCESS_VM_READ'权限。实际上,他们甚至使用'PROCESS_QUERY_LIMITED_INFORMATION'权限。 –

+0

你确定*它不是一个API函数,@Remy? http://msdn.microsoft.com/en-us/library/windows/desktop/ms633517.aspx –

+0

@RobKennedy:我学到了一些新东西。我以前从来没有听说过这个API函数。但是,我没有看到它的文档中的任何内容禁止它获取属于另一个进程的窗口的文件名。 AFAIK该限制仅适用于'GetModuleFileName()',其文档是Marko引用的。我将不得不测试'GetWindowModuleFileName()'并且看看会发生什么。 –

3

GetActiveWindow仅获取属于调用线程的活动窗口的窗口句柄。

您需要使用GetForegroundWindow()函数而不是GetActiveWindow()

相关问题