belly Geschrieben 20. September 2002 Geschrieben 20. September 2002 Guten Morgen allerseits!:cool: Ich möchte eine Art-Taskmanager programmieren. Ich arbeite mit Visual c++ und benutze den BCB 5.0. Das ganze soll auf Windows NT laufen. Habe es bis jetzt geschaft mir Titel, ProcessId und Speichernutzung auszulesen, aller Prozese die in der Taskleiste aufgeführt sind: HANDLE hProcess; //Processhandle DWORD pid; //Für ProcessId char pcWinTitle[256]; // Für Fenster-Titel... // Falls kein Child-Fenster: if(!GetWindow(hwnd, GW_OWNER)) { // Fenster-Title (Caption) auslesen: GetWindowText(hwnd, pcWinTitle, 255); // Falls Titel vorhanden in die Listbox einfügen: if(AnsiString(pcWinTitle).Trim() != EmptyStr) { FormPrc -> CheckListBox1 -> Items->Add (pcWinTitle); // Ausgabe Prozesstitel GetWindowThreadProcessId(hwnd, &pid); //Nur mal so als Überblick;) Wenn ihr Euch den Taskmanager anguckt, komme ich nun zu meiner ersten Frage: Wo ist der unterschied zwischen einer Anwendung und einem Prozess, durch welches merkmal kann ich diese unterscheiden? Ich würde gerne eine seperate Liste für Anwendungen und eine für Prozesse haben. :confused: 2. Da ich ja praktisch die Taskleiste auslese, komme ich natürlich nicht an alle Prozesse heran. Wie komme ich an die Prozesse die sich im "Hintergrund" befinden? z.B. SMSS.EXE, WINLOGON.EXE, comsmd.exe etc. (Taskmanager mal angucken) Ich als IT-Newbie bin ja schon froh überhaupt so weit gekommen zu sein :marine Hoffe das mir jemand noch ein bißchen weiterhelfen kann. Mfg belly Zitieren
Guybrush Threepwood Geschrieben 20. September 2002 Geschrieben 20. September 2002 Hi, versuchs mal mit der Funktion CreateToolhelp32Snapshot, die erstellt nämlich je nach Parameter eine Liste aller Processe, Threads usw. Danach kannst du dann mit den Funktionen Process32First und Process32Next die einzelnen Processe auslesen, wobei Daten wie die ProzessID in einem Struct gespeichert werden. Ich weiß gar nicht ob es überhaupt einen Unterschied zwieschen einer Anwendung und einem Process gibt, weil jede Anwendung ja aus einem Process besteht. Gruß wasweißich Zitieren
belly Geschrieben 20. September 2002 Autor Geschrieben 20. September 2002 unter Win NT4 gibt es diese API im Kernel32 nicht mehr...leider...komischerweise haben die Microsoftler diese API unter Win2000 wieder eingeführt... Die Fehlermeldung bestätigt dies: Der Prozedureneinstiegspunkt "CreateToolhelp32Snapshot" konnte in der Dynamic Link Library "Kernel32.DLL" nicht gefunden werden. und nu? Zitieren
Klotzkopp Geschrieben 20. September 2002 Geschrieben 20. September 2002 Dann musst Du Dich mit EnumProcesses und den anderen psapi-Funktionen begnügen. Die gibt es auch für NT4. Zitieren
Guybrush Threepwood Geschrieben 20. September 2002 Geschrieben 20. September 2002 Das ist natürlich blöd:( , in der MSDN steht auch das man mind. NT5.0 braucht. Ich hab hier noch ein Stück Code (keine Ahnung mehr woher) mit dem man angeblich (hatte bei mir nicht geklappt) einen Process aus dem Taskmanager entfernen kann, also verstecken, indem man im Kernel die Registrierung löscht. Man müßte so also auch irgendwie die im Kernel registrierten Processe bekommen.Vielleicht hilft dir das ja: typedef DWORD (CALLBACK* TRegProc)(DWORD, DWORD); HINSTANCE Kern; TRegProc RegProc; Kern = LoadLibrary("KERNEL32.DLL"); if(Kern) { RegProc = (TRegProc)GetProcAddress(Kern, "RegisterServiceProcess"); //Hier //andere Funktion angeben um Process zu bekommen. if(RegProc) RegProc(GetCurrentProcessId(),1); FreeLibrary(Kern); } [/PHP] Gruß wasweißich Zitieren
Klotzkopp Geschrieben 20. September 2002 Geschrieben 20. September 2002 Original geschrieben von wasweißich Ich hab hier noch ein Stück Code (keine Ahnung mehr woher) mit dem man angeblich (hatte bei mir nicht geklappt) einen Process aus dem Taskmanager entfernen kann, also verstecken, indem man im Kernel die Registrierung löscht. Da wird nichts gelöscht, sondern der Prozess wird als Dienst gekennzeichnet. Dienste werden im Taskmanager nicht aufgeführt. Bei der Verwendung dieses Codes ist übrigens Vorsicht angebracht. Ein als Dienst registrierter Prozess wird nicht beendet, wenn der Benutzer sich abmeldet. Zitieren
Guybrush Threepwood Geschrieben 20. September 2002 Geschrieben 20. September 2002 Danke für die Info Klotzkopp, dann ists ja gut das ich damit ausser ein, zweimal ausprobieren keine Programme bestückt habe. Kennst du vielleicht eine Kernelfunktion um gestartete Process zu erhalten, bei mir auf der Arbeit klappt nämlich irgendwie die dumpbin exe nicht, mit der kann man sich ja eine Liste aller exportierten Funktionen einer DLL anschauen. Zitieren
Klotzkopp Geschrieben 20. September 2002 Geschrieben 20. September 2002 Original geschrieben von wasweißich Kennst du vielleicht eine Kernelfunktion um gestartete Process zu erhalten, bei mir auf der Arbeit klappt nämlich irgendwie die dumpbin exe nicht, mit der kann man sich ja eine Liste aller exportierten Funktionen einer DLL anschauen. Wie schon gesagt, EnumProcesses. Ist aber nicht im Kernel, sondern in psapi.dll. Dafür gibts sogar .lib und .h, also brauchst Du nicht mal LoadLibrary . Zitieren
belly Geschrieben 21. September 2002 Autor Geschrieben 21. September 2002 Original geschrieben von Klotzkopp Dann musst Du Dich mit EnumProcesses und den anderen psapi-Funktionen begnügen. Die gibt es auch für NT4. Richtig, leider weiß ich trotzdem nicht genau wie ich an die Prozesse herankommen soll. Mir fehlt da wohl auch ein wenig Erfahrung im Programmieren mit C++. Aber danke für die schnelle Hilfe mfg Belly Zitieren
Guybrush Threepwood Geschrieben 23. September 2002 Geschrieben 23. September 2002 Hi, also als ersten Parameter mußt du EnumProcesses ein Array übergeben welches die Process IDs bekommt. Das Array sollte ziemlich groß sein da du ja nicht weißt weiviele IDs du bekommst (schau mal im Taskmanager nach und machs ein bischen größer), dann mußt du als zweiten Parameter die Größe des Arrays übeergeben und schließlich eine Variable die die Größe des neuen Arrays enthalten wird (um zu ermitteln wieviele IDs zurückgeliefert wurden teile die Größe durch sizeof(DWORD). Ungefähr so: DOWRD dwIDs[200], dwAnz = 200, dwSize=0; int nAnzahlIDs=0; EnumProcesses(&dwIds,dwAnz,&dwSize); nAnzahlIDs = dwSize / sizeof(DWORD); [/PHP] Müßte eigentlich so funktionieren (habs noch nicht probiert), die einzelnen Processe kannst du dann mit [i]OpenProcess[/i] öffnen. Gruß wasweißich Zitieren
Leana Geschrieben 23. September 2002 Geschrieben 23. September 2002 hier ist der code, der dir die prozesse ermittelt und noch die verwendeten dll und exe ausgibt!!! //geht auch nur unter nt wenn vorhanden //ansonsten unter 2000 und xp schon //bekommt alle aktiven prozess-ids void CSystemInfo::EnumProc() { // Get the list of process identifiers. DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; HINSTANCE m_hInstance; m_hInstance = LoadLibrary("PSAPI.DLL"); //wenn wir die library laden konnten if(m_hInstance) { EnumProcesses_ProcPtr lpfnDLLProc = NULL; lpfnDLLProc = (EnumProcesses_ProcPtr) GetProcAddress(m_hInstance, "EnumProcesses"); if(lpfnDLLProc) { if ( !lpfnDLLProc( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return; // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); // Print the name of the modules for each process. for ( i = 0; i < cProcesses; i++ ) PrintModules( aProcesses ); } } } void CSystemInfo::PrintModules( DWORD processID ) { HMODULE hMods[1024]; HANDLE hProcess; DWORD cbNeeded; unsigned int i; // Print the process identifier. printf( "\nProcess ID: %u\n", processID ); // Get a list of all the modules in this process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); HINSTANCE m_hInstance; m_hInstance = LoadLibrary("PSAPI.DLL"); //wenn wir die library laden konnten if(m_hInstance) { EnumProcessModules_ProcPtr lpfnDLLProc = NULL; lpfnDLLProc = (EnumProcessModules_ProcPtr) GetProcAddress(m_hInstance, "EnumProcessModules"); if(lpfnDLLProc) { if( lpfnDLLProc(hProcess, hMods, sizeof(hMods), &cbNeeded)) { for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ ) { char szModName[MAX_PATH]; // Get the full path to the module's file. GetModuleFileNameEx_ProcPtr lpfnDLLProc = NULL; lpfnDLLProc = (GetModuleFileNameEx_ProcPtr) GetProcAddress(m_hInstance, "GetModuleFileNameExA"); if ( lpfnDLLProc( hProcess, hMods, szModName, sizeof(szModName))) { // Print the module name and handle value. printf("\t%s (0x%08X)\n", szModName, hMods ); } } } else DWORD fehler = GetLastError(); } } CloseHandle( hProcess ); } Zitieren
Klotzkopp Geschrieben 23. September 2002 Geschrieben 23. September 2002 Kleine Anmerkung: Von Microsoft gibt es das kostenlose Platform SDK (Software Development Kit). Darin (genauer gesagt im Core SDK) gibt es eine psapi.h und psapi.lib. Damit erspart man sich das Laden der DLL zur Laufzeit. Zitieren
Leana Geschrieben 24. September 2002 Geschrieben 24. September 2002 Das ist mir klar, da ich das programm aber auch unter 98 verwende muss ich das auf diesen weg machen, da 98 psapi nicht kennt, und fehler werfen würde!!! Zitieren
belly Geschrieben 24. September 2002 Autor Geschrieben 24. September 2002 Ein dickes herzliches Dankeschön... *ordenverteil*:bimei Zitieren
TinTin Geschrieben 27. August 2003 Geschrieben 27. August 2003 hi, ich bekomme hier [COLOR=orangered]EnumProcesses_ProcPtr[/COLOR] lpfnDLLProc = NULL; lpfnDLLProc = (EnumProcesses_ProcPtr) GetProcAddress(m_hInstance, "EnumProcesses"); immer die mitteilung 'nichtdeklarierter bezeichner', finde aber auch nichts zu diesem datentyp!? ich hab die beiden funktionen 'EnumProc()' und 'PrintModules(DWORD processID)' als member funktionen in mein projekt (vc++ 6.0/mfc) eingebunden. muss ich sonnst noch was beachten??? Ciao TinTin PS: ich hab bestimmt wieder was nicht gesehen oder so... Zitieren
Guybrush Threepwood Geschrieben 27. August 2003 Geschrieben 27. August 2003 Versuchs mal mit folgender Zeile: typedef BOOL (CALLBACK* EnumProcesses_ProcPtr)(DWORD*, DWORD, DWORD*); Zitieren
TinTin Geschrieben 27. August 2003 Geschrieben 27. August 2003 ok, das hat geholfen, bis zum nächsten fehler... C:\projekte\process\processDlg.cpp(249) : error C2065: 'EnumProcessModules_ProcPtr' : nichtdeklarierter Bezeichner C:\projekte\process\processDlg.cpp(249) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'lpfnDLLProc' C:\projekte\process\processDlg.cpp(249) : error C2065: 'lpfnDLLProc' : nichtdeklarierter Bezeichner C:\projekte\process\processDlg.cpp(251) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'GetProcAddress' C:\projekte\process\processDlg.cpp(266) : error C2065: 'GetModuleFileNameEx_ProcPtr' : nichtdeklarierter Bezeichner C:\projekte\process\processDlg.cpp(266) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'lpfnDLLProc' C:\projekte\process\processDlg.cpp(268) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'GetProcAddress' ich hab dann entsprechend typedefs für die anderen datentypen angelegt: typedef BOOL (CALLBACK* EnumProcesses_ProcPtr)(DWORD*, DWORD, DWORD*); typedef BOOL (CALLBACK* EnumProcessModules_ProcPtr)(DWORD*, DWORD, DWORD*); typedef BOOL (CALLBACK* GetModuleFileNameEx_ProcPtr)(DWORD*, DWORD, DWORD*); bekomme dann folgende fehlermeldung: C:\projekte\process\processDlg.cpp(258) : error C2197: 'int (__stdcall *)(unsigned long *,unsigned long,unsigned long *)' : Zu viele Parameter uebergeben C:\projekte\process\processDlg.cpp(271) : error C2197: 'int (__stdcall *)(unsigned long *,unsigned long,unsigned long *)' : Zu viele Parameter uebergeben im code werden 4 parameter übergeben, ich hab aber nur 3 definiert. lpfnDLLProc(hProcess, hMods, sizeof(hMods), &cbNeeded) wenn ich noch ein 4 DWORD in den typedef schreibe, dann flippt alles aus. typedef BOOL (CALLBACK* GetModuleFileNameEx_ProcPtr)(DWORD*, DWORD, DWORD*, DWORD*); C:\projekte\process\processDlg.cpp(271) : error C2664: 'int (unsigned long *,unsigned long,unsigned long *,unsigned long *)' : Konvertierung des Parameters 4 von 'unsigned int' in 'unsigned long *' nicht moeglich Die Konvertierung eines ganzzahligen Typs in einen Zeigertyp erfordert ein reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat ich steh hier wieder ein wenig auf dem schlauch... darf ich das nicht als DWORD oder DWORD* vereinbaren? wenn nicht, wie denn dann??? Ciao TinTin Zitieren
Guybrush Threepwood Geschrieben 27. August 2003 Geschrieben 27. August 2003 Richtig, du solltest schon nachkucken welche Parameter die Funktionen erwarten;) BOOL EnumProcesses( DWORD * lpidProcess, // array to receive the process identifiers DWORD cb, // size of the array DWORD * cbNeeded // receives the number of bytes returned ); BOOL EnumProcessModules( HANDLE hProcess, // handle to the process HMODULE * lphModule, // array to receive the module handles DWORD cb, // size of the array LPDWORD lpcbNeeded // receives the number of bytes returned ); DWORD GetModuleFileNameEx( HANDLE hProcess, // handle to the process HMODULE hModule, // handle to the module LPTSTR lpFilename, // buffer that receives the path DWORD nSize // size of the buffer ); Nächstes mal selber kucken:) Zitieren
TinTin Geschrieben 27. August 2003 Geschrieben 27. August 2003 ok!!! ich hatte schon mal in der msdn nach GetModuleFileNameEx_ProcPtr gesucht und nichts gefunden, jetzt wundert mich das nicht mehr. danke, jetzt hab ich erst kapiert was ich da eigentlich mache. mein erstes typedef... Ciao TinTin Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.