HANDLE in HWND umwandeln ??



  • Hy Leute,

    ich hab' da mal ne Frage: Wie ermittle ich das Handle eines Fensters mit Hilfe des exe_Namens?

    Bsp.:
    programm.exe -> GetFensterHandle("programm.exe") o.ä.

    GetFensterHandle() steht vereinfacht für die Funktion, die ich suche!

    Bis jetzt klappt das bei mir nur mit dem Fenstertitel:

    HWND hFenster = FindWindow(NULL, "Fenstertitel");

    Hat jemand von euch ne Idee?



  • Hier gibts das in Delphi.
    Schau dir vor allem die API Funktionen an.

    http://www.dsdt.info/tipps/?id=638

    MFG
    Ace



  • tsp schrieb:

    Hy Leute,

    ich hab' da mal ne Frage: Wie ermittle ich das Handle eines Fensters mit Hilfe des exe_Namens?

    Das sagt eigentlich relativ wenig aus, da ein Prozess ( ➡ mit einem 'exe_Namen' adressiert Du ja mehr oder weniger den Prozess) auch mehrere Fenster haben kann ⚠ .



  • Wir gehen einfach mal davon aus, dass der Prozess nur ein Fenster hat!



  • Ok, ich ändere mal die Frage etwas ab:

    Wie kann ich ein HANDLE h in ein HWND hwnd umwandeln?? 😕

    HANDLE h=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID);            
    // h in hwnd ??
    SendMessage(hwnd,WM_CLOSE,(LPARAM)0,(WPARAM)0);
    

    Kann mir jemand helfen?



  • tsp schrieb:

    Wie kann ich ein HANDLE h in ein HWND hwnd umwandeln??

    Geht nicht. Ein Prozesshandle und ein Fensterhandle sind zwei völlig verschiedene Dinge.



  • Du kannst dir aber die HWNDs des Prozesses ausgeben lassen.
    Ich weiß grad nicht (mehr welche API Funktion man das kann, aber es geht auf jeden Fall.



  • tsp schrieb:

    Wir gehen einfach mal davon aus, dass der Prozess nur ein Fenster hat!

    lol, ne machen wir nicht :p .

    Also:
    Du kannst mit der Funktion OpenProcess einen Handle auf einen Prozess ermitteln, dafür wird aber die ID benötigt... . Alternativ kannst Du alle verfügbaren Prozesse enumerieren (d.h. aufzählen), nämlich mit der Funktion CreateToolhelp32Snapshot. Mit der Funktion GetModuleFileName kannst Du Dir dann einen Pfad zum entsprechenden Handle holen und diesen ggf. vergleichen (lstrcmp). Da aber, wie ich schon sagte, ein Prozess mehrere Fenster haben kann und davon gehe ich jetzt auch einfach mal aus, da das eigentlich meistens so ist (außerdem ist die Vorgehensweise bei einem Prozess, der sicher nur ein Fenster hat gleich), ist Folgendes zu tun: Mit der Funktion EnumWindows kannst Du Dir, in Kombination mit einer von Dir definierten Funktion, deren Adresse dann an die Funktion EnumWindows übergeben wird ( ➡ 'callback'-Prinzip), alle existierenden Fenster enumerieren lassen. Um zu unterscheiden, welches Fenster nun zu einen bestimmten Prozess gehört, musst Du den Prozesshandle, den Du über OpenProcess/CreateToolhelp32Snapshot ermittelt hast, mit denen der Fenster vergleichen. Den Prozesshandle zu einem bestimmten Fenster bekommst Du über die Funktion GetWindowThreadProcessId in Kombination mit OpenProcess.

    Wobei man diesen Weg auch andersrum beschreiten kann 😉 .

    Hoffe das hilft Dir.



  • Vielen Dank für eure Antworten,

    hat vllt. jmd. mal ein Beispielcode (nur en Fetzen, muss nichts komplettes sein) ?



  • Glaube sowas ist zu spezifisch, da findeste keinen Beispielcode, vllt suchst Du mal bei www.koders.com, da findet man manchmal ganze Programme, wo soetwas zur Verwendung kommt 😉 .



  • tsp schrieb:

    hat vllt. jmd. mal ein Beispielcode ...

    Formuliere Deine Frage mal im Sinne von "Gegeben / Gesucht / Aktion".
    Beispiel :
    Gegeben : Fensterhandle
    Gesucht : ProzessID
    Aktion : Prozess beenden



  • Hm...man kann aber nicht jede Frage auf so ein 'Muster' runterbrechen; nur so BTW.



  • Ok, für merker:

    Gegeben: HANDLE
    Gesucht: HWND
    Aktion: Ermittle über Prozessnamen das HANDLE und will mit SendMessage(hwnd,WM_CLose,...) den Prozess mit HWND beenden!

    Für alle anderen: Neue Frage: Wie beende ich ein Prozess (HANDLE hab ich) ordentlich (also nicht mit TerminateProcess ➡ klappt bei mir eh nich)



  • tsp schrieb:

    Gegeben: HANDLE
    Gesucht: HWND
    Aktion: Ermittle über Prozessnamen das HANDLE und will mit SendMessage(hwnd,WM_CLose,...) den Prozess mit HWND beenden!

    Zunächst mal grundsätzliches :

    Ein Betriebssystem kann 1 oder viele Prozesse haben.
    Ein Prozess kann 1 oder viele Threads haben.
    Ein Thread kann 0, 1 oder viele HWND's (Fenster) haben.

    Der Prozessname alleine ist einfach nicht eindeutig genug. Das musst Du bei folgendem Beispielcode immer im Hinterkopf haben :

    // Ermittelt HWND's von Prozessen bei denen nur der "Name" bekannt ist
    
    #include <windows.h>
    #include <tlhelp32.h> 
    
    BOOL CALLBACK EnumThreadWndProc ( HWND hwnd, LPARAM lParam ) {
    // Hier hast Du Zugriff auf die HWND's des Prozesses
    // Hier gilt : "Do At Your Own Risk" :-) Kleine Auswahl :
    
    // PostMessage       (hwnd,WM_QUIT, 0,0);
    // PostMessage       (hwnd,WM_CLOSE,0,0);
    // PostThreadMessage ((DWORD) lParam,WM_QUIT,0,0);
    // PostThreadMessage ((DWORD) lParam,WM_SYSCOMMAND,SC_CLOSE,0);
    
     return TRUE;
    }
    
    WINAPI        WinMain           (HINSTANCE, HINSTANCE, LPSTR, int) {
    
     TCHAR          *cProcessName = "taskmgr.exe"; // der gesuchte Prozess
    
     HANDLE          hSnapProcess;
     HANDLE          hSnapThread;
     PROCESSENTRY32  processInfo; processInfo.dwSize = sizeof (processInfo);
     THREADENTRY32   threadInfo;  threadInfo.dwSize  = sizeof (threadInfo);
    
    // 1. Alle Prozesse finden die cProcessName heissen
     hSnapProcess  = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS,0);
    
     Process32First (hSnapProcess,&processInfo);
    
     do {
    
    // Wenn ein Prozess gefunden wurde, dann ...
      if ( !lstrcmpi (processInfo.szExeFile,cProcessName) ) { // nicht case-sensitive
    
    // 2. Alle Threads finden, die zu diesem Prozess gehören
       hSnapThread = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD,0);
    
       Thread32First (hSnapThread,&threadInfo);
    
       do {
    
    // Wenn ein Thread gefunden wurde, der zum Prozess gehört, dann ...
        if (threadInfo.th32OwnerProcessID == processInfo.th32ProcessID) {
    
    // 3. Alle HWND's via CALLBACK suchen, die zum Thread gehören
         EnumThreadWindows (threadInfo.th32ThreadID,(WNDENUMPROC) EnumThreadWndProc,threadInfo.th32ThreadID);
    
        }
    
       } while ( Thread32Next (hSnapThread,&threadInfo) );
    
       CloseHandle    (hSnapThread);
      }
    
     } while ( Process32Next  (hSnapProcess,&processInfo) );
    
     CloseHandle    (hSnapProcess);
    
     return 0;
    }
    


  • ...
    // EDIT : versehentlich zweimal auf Absenden geklickt
    ...



  • Vielen Dank merker, hat mir sehr geholfen! 🙂

    Aber ich hab doch noch mal die konkrete Frage:

    Wie kann ich einen Prozess beenden??? 😡 (Gegeben: ProzessID, HANDLE)

    Edit:

    Ich hab mal ein bisschen probiert:

    int isRun(string file)
    {
        HANDLE hSnapShot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0);
    
        PROCESSENTRY32 processInfo; processInfo.dwSize = sizeof (processInfo);
    
        /*PROCESSENTRY32* processInfo = new PROCESSENTRY32;
        processInfo->dwSize = sizeof ( PROCESSENTRY32);*/
    
        while ( Process32Next ( hSnapShot,&processInfo ) != FALSE)
        {
            if (strcmp(processInfo.szExeFile,file.c_str())==0)return processInfo.th32ProcessID;
        };
    
        CloseHandle ( hSnapShot);
    
        //delete processInfo;
        return 0;
    }
    
    int main()
    {    
        while (true)
        {
            Sleep(5);        
            int i=isRun("notepad.exe");
            if (i!=0)
            {            
                LPDWORD lpd;
                HANDLE h=OpenProcess(PROCESS_ALL_ACCESS,FALSE,i);
                TerminateProcess(h,GetExitCodeProcess(h,lpd));            
                CloseHandle(h);   
            }
        }    
        return 0;
    }
    

    Das klappt bei mir aber nicht! Es gibt zwar keine Fehlermeldung beim Kompilieren, aber beim Ausführen stürzt das Prog. immer ab! Warum?



  • tsp schrieb:

    ...aber beim Ausführen stürzt das Prog. immer ab! Warum?

    GetExitCodeProcess () erwartet als 2. Parameter die Adresse eines DWORD's :

    DWORD lpd;
    ...
    GetExitCodeProcess(h,&lpd));
    ...
    

    Falls strcmp () Gross- und Kleinschreibung beachtet, könnte es Probleme mit dem Prozessnamen geben ( -> notepad.exe != NOTEPAD.EXE <- ).
    Deine main () enthält eine Endlosschleife. Willst Du verhindern, dass jemand notepad.exe startet ? 🙂

    tsp schrieb:

    Wie kann ich einen Prozess beenden??? (Gegeben: ProzessID, HANDLE)

    Dazu reicht die ProzessID :

    DWORD  dwProcessID = 1234;
     DWORD  dwExitCode;
     HANDLE hProcess;
    
    // 3. Parameter : ProzessID (DWORD)
     hProcess   = 
     OpenProcess        (PROCESS_ALL_ACCESS,FALSE,dwProcessID); 
    
    // 1. Parameter : ProzessHANDLE (HANDLE), von OpenProcess () geliefert
    // 2. Parameter : ExitCode (kann selbst festgelegt werden, alle Zahlen erlaubt ausser STILL_ACTIVE)
     TerminateProcess   (hProcess,12); 
    
    // Aufruf nicht notwendig, da ja bekannt ist warum der Prozess beendet wurde :-)
    // Würde "12" als ExitCode liefern
     GetExitCodeProcess (hProcess,&dwExitCode); 
    
     CloseHandle        (hProcess);
    


  • ⚠ ➡

    MSDN schrieb:

    he TerminateProcess function is used to unconditionally cause a process to exit. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.

    TerminateProcess initiates termination and returns immediately. This stops execution of all threads within the process and requests cancellation of all pending I/O. The terminated process cannot exit until all pending I/O has been completed or canceled.

    A process cannot prevent itself from being terminated.
    Requirements

    💡 ➡ Terminating a Process



  • Vielen Dank!! 🙂 🙂

    Jetzt funktioniert das mit TerminateProcess.
    Aber ich musste leider wirklich feststellen, dass das mit TerminateProcess nicht so toll ist. 😞 Es bleiben immer Programmreste übrig, die Prozesse sind nie richtig beendet. Gibt es da nicht ne Möglichkeit (besser als TerminateProcess), alle Threads eines Prozesses mit zu beenden, sodass keine Reste mehr im Speicher sind ( ➡ so wie "Prozess beenden" im Task-Manager!) ?



  • www.webfritzi.de.vu --> WinAPI-Ecke --> Units --> Unit "AppTerminating"


Anmelden zum Antworten