2009-03-29 7 views
3

Ich habe eine Anwendung, die Menschen mit Behinderungen hilft. Um zu arbeiten, verfolgt es, welches Fenster gerade im Vordergrund ist. Normalerweise verwende ich diese Funktion, um den Prozess ausführbar zu machen.Wie kann ich den Prozess Dateinamen unter Vista bekommen?

bool GetWindowProcessExe2(HWND hwnd, wxString& process_exe) 
         //LPTSTR buf, DWORD size) 
{ 
DWORD result = 0; 
DWORD pid = 0; 
GetWindowThreadProcessId(hwnd, &pid); 
if (HANDLE process = 
    OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid)) 
{ 
    char buff[512]; 
    LPTSTR pbuff = buff; 
    result = GetModuleFileNameEx(process, 0, pbuff, 512); 
    if(result == 0) 
    { 
    //failed. 
    wxLogError("GetModuleFileNameEx failed with error code %d", GetLastError()); 
    } 
    CloseHandle(process); 
    process_exe = fromCString(pbuff); 
} 

return result > 0 ? true : false; 

}

Leider, wenn das Fenster im Vordergrund ist das Vista-Datei-Manager-Fenster (das Fenster, wenn Sie öffnet Start- klicken> Computer), schlägt fehl GetModuleFileNameEx() mit dem Fehlercode 299, der sagt, dass ich dies nicht tun haben Privilegien für diese Aktion. Mein Code funktioniert für jede normale Anwendung, aber nicht für das Windows-Fenster (den Datei-Explorer). Ich muss wissen, wann dieses Fenster im Vordergrund steht. Gibt es einen anderen Weg, es zu tun? Ich habe versucht, den Fenstertitel zu lesen, aber das zeigt nur das aktuelle Verzeichnis an. Irgendwelche Ideen?

+0

hatte dasselbe Problem, verwenden Sie ['GetProcessImageFileName'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683217 (v = vs.85) .aspx) stattdessen – user1438233

Antwort

2

Ich bin mir nicht sicher, warum dies nicht für Explorer funktioniert, aber Fehler 299 ist ERROR_PARTIAL_COPY, was bedeutet, dass der Versuch, den Modulnamen aus Explorer zu lesen fehlschlägt.

Unter Vista, bevorzugen Sie QueryProcessImageFileName und öffnen Sie nur den Prozess mit PROCESS_QUERY_LIMITED_INFORMATION - Ihr Code wird in mehreren Fällen funktionieren.

WCHAR exeName[512]; 
DWORD cchExeName = 512; 
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid); 
QueryFullProcessImageName(process, 0, exeName, &cchExeName); 

EDIT: Ich habe auch ERROR_PARTIAL_COPY mit Ihrem Code auf 64-Bit ausgeführt wird, aber nur dann, wenn der anfragende Prozess 32-Bit war. 64-Bit/64-Bit hat gut funktioniert.

+0

Danke für die Hilfe; Ich schätze es! Ich habe Probleme beim Verknüpfen des Code-Snippets. Ich bekomme einen Linker-Fehler: LNK2019 nicht aufgelöst extern, Symbol __imp__QueryFullProcessImageNameA @ 16 in Funktion referenziert .... Ich habe kernel32.lib enthalten. Ich entwickle auf Vista 64, wenn es darauf ankommt. Ich benutze psdk 2003. – max

+1

QueryFullProcessImageName wäre nicht im SDK 2003, da es mit Vista eingeführt wurde. Wenn das Aktualisieren des SDK keine Option ist, können Sie LoadLibrary/GetProcAddress verwenden, um QueryFullProcessImageName abzurufen. – Michael

1

Sieht so aus, als ob ein 32-Bit-Prozess GetModuleFileNameEx nur bei anderen 32-Bit-Prozessen aufrufen kann. Wenn Sie versuchen, es auf 64-Bit-Prozessen aufzurufen, schlägt es mit ERROR_PARTIAL_COPY fehl. Auf einer 64-Bit-Plattform machen Sie den aufrufenden Prozess 64 Bit und Sie sollten in der Lage sein, GetModuleFileNameEx sowohl für 64- als auch für 32-Bit-Prozesse aufzurufen.

Verwandte Themen