XspYroX Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 Moin Habe ein echt schwieriges Problem hier. Ich habe einen Dienst programmiert, der die laufenden Prozesse auf unbekannte (nicht-gewhitelistete) prozesse prüft und diese ausgibt bzw. in eine datenbank hochlädt. Jetzt habe ich gestern einen kleinen code-teil hinzugefügt und... naja, er wird schlicht und ergreifend nicht ausgeführt :/ Habe mich dann mit test-ausgaben zu der stelle gehangelt, wo er den code dann nicht mehr ausführt und es handelt sich dabei um das ende einer foreach-schleife. Hier der für euch interessante code-teil: static void checkScan() { bool isWhitelisted = false; bool skipproc = false; log("Scan gestartet (" + DateTime.Now.ToString() + ")"); foreach (Process p in Process.GetProcesses()) { skipproc = false; isWhitelisted = false; double proclength = new FileInfo(p.MainModule.FileName.ToString().ToLower()).Length; log("name=" + p.MainModule.FileName.ToString().ToLower()); // Statische Scan-Ausnahmen if (p.Id > 50) { if (p.MainModule.FileName.ToString().ToLower().Contains("c:\\xampp\\") == true) { skipproc = true; } if (p.MainModule.FileName.ToString().ToLower().Contains("\\inappx_64.bin") == true) { skipproc = true; } if (p.MainModule.FileName.ToString().ToLower().Contains(".vshost.exe") == true) { skipproc = true; } if (p.MainModule.FileName.ToString().ToLower().Contains("\\testtool.exe") == true) { log("testtool-prozess gefunden, pruefe echtheit..."); // testtool.exe ist 1694208 lang if (proclength.ToString() == "1694208") { skipproc = true; } } if (skipproc == false) { try { for (int i = 0; i < whitelistGlobal.Length; i++) { if (whitelistGlobal[i].ToLower() == p.MainModule.FileName.ToString().ToLower()) { isWhitelisted = true; } } if (isWhitelisted == false) { log("Prozess gefunden: " + p.MainModule.FileName.ToString().ToLower()); uploadDb(p.MainModule.FileName.ToString().ToLower()); log("test1"); } log("test2"); } catch (Exception e) { log("Fehler beim abrufen des Prozesses mit der PID[" + p.Id.ToString() + "] :"); log(e.ToString()); } } log("test3"); } log("test4"); } log("checkscan-foreach zuende"); } Im Log-file stehen dann die vielen "test3" und "test4" drin, aber die zeile log("checkscan-foreach zuende"); wird einfach nie ausgeführt. Also ... die foreach-schleife wird ja anscheinend korrekt ausgeführt. Der Dienst stürzt auch nicht ab oder startet neu, er läuft flüssig durch. Bisher ist das nie aufgefallen, weil der dienst eine aktion ("checkscan()") alle x minuten ausführt und dort, wo das "checkscan-foreach zuende" ausgegeben werden sollte, normalerweise nichts mehr steht und er dann x minute wartet und wieder von vorn anfängt. Bestimmt übersehe ich irgendwas dämliches, aber ich komm einfach nicht drauf Wenn ihr noch irgendwelche infos braucht, fragt. Im log steht am ende übrigens immer "test4", wodurch man eigentlich auch fehler im zusammenhang mit dem foreach ausschließen kann. Denn wenn nach dem "test4" nochmal ein prozess an der reihe wäre, würde er den prozess noch einmal ausgeben. Wenn also "test4" am ende steht, und das tut es, hat die foreach-schleife keinen fehler. Aber wieso wird dann die zeile dadrunter nicht ausgeführt? Ich steh sowas von auf dem schlauch ._. Danke für jeden Versuch der hilfe >_> Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
uenetz Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 Dann kann der Fehler wohl nur hier liegen: foreach (Process p in Process.GetProcesses()) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David1993 Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 Ja. Binde LINQ ein: using System.Linq; und verändere dein foreach Statement nach: foreach (Process p in Process.GetProcesses().ToList()) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 Ja. Binde LINQ ein: using System.Linq; und verändere dein foreach Statement nach: foreach (Process p in Process.GetProcesses().ToList()) Hmm... was macht "Process.GetProcesses().ToList()" denn anders als meine Zeile? Muss ich das dann später auch anders verarbeiten? Ich benutzr später ja auch z.b. "p.MainModule.FileName.ToString().ToLower().Contains...". Kann ich auf die unterfunktiontn wie bisher zugreifen? Sorry, Linq sagt mir eigentlich nichts, bin gerade dabei mich da etwas schlau zu machen^^" Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David1993 Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 Okay. Dann lade die Prozessliste vor Beginn der Schleife. also: var prozesse = Process.GetProcesses(); foreach(var p in prozesse) { ... } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 Okay. Dann lade die Prozessliste vor Beginn der Schleife. also: var prozesse = Process.GetProcesses(); foreach(var p in prozesse) { ... } Hab beide varianten von dir ausprobiert, beide ändern leider nichts Der letzte log-eintrag ist und bleibt "test4". Hat vielleicht jemand ne idee, wie ich das mit der foreach-schleife noch besser debuggen kann? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David1993 Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 1. Gehe jeden Prozess einzeln mit dem Debugger durch oder 2. Umfasse die gesamte Schleife mit einem try-catch Block und setze im "catch"-Block einen Breakpoint. try{ foreach(..){ ... } } catch(Exception ex){ # Breakpoint } finally{ # Breakpoint } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 Ok, das mit dem try-catch war genial. Folgenden Error wirft er mir aus: System.ComponentModel.Win32Exception (0x80004005): Die Prozessmodule konnten nicht aufgelistet werden. bei System.Diagnostics.NtProcessManager.GetModuleInfos(Int32 processId, Boolean firstModuleOnly) bei System.Diagnostics.Process.get_MainModule() bei alfaSecuSvr.service.checkScan() Allerdings greife ich ja nicht auf ein bestimmtes Attribut eines Prozesses zu, der Fehler wird ja schon vorher provoziert. Ich kann mit dieser fehlermeldung gerade nicht wirklich was anfangen... er will das mainmodule abrufen und das scheitert. Weitere Ideen? Aber erstmal danke für den tipp. Hätte nicht gedacht, dass bei getprocecces() was schiefgehen kann, so kann man sich irren^^" Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 Allerdings greife ich ja nicht auf ein bestimmtes Attribut eines Prozesses zu Process.get_MainModule Pseudoprozesse wie Idle haben kein MainModule. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David1993 Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 (bearbeitet) Das ist eine Erklärung. Eine andere wäre, dass ein 32 Bit Prozess versucht auf einem 64 Bit Prozess zuzugreifen. Schau dir den Punkt "Ausnahmen" an. Dort findest du die Erklärung, warum dort eine Win32Exception geworfen wird. Process.MainModule-Eigenschaft (System.Diagnostics) 1. Lösungsvorschlag: Umfasse den Abruf mit einem try-catch und logge, wenn ein Prozess nicht abgerufen werden konnte. 2. Lösungsvorschlag: Du rufst nur die Prozesse ab, die keine "Pseudoprozesse" sind, mit: foreach (var p in Process.GetProcesses().Where(x=>x.StartInfo.UseShellExecute==false).ToList()) { ... } Bearbeitet 5. September 2013 von David1993 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 Das ist eine Erklärung. Eine andere wäre, dass ein 32 Bit Prozess versucht auf einem 64 Bit Prozess zuzugreifen. Schau dir den Punkt "Ausnahmen" an. Dort findest du die Erklärung, warum dort eine Win32Exception geworfen wird. Process.MainModule-Eigenschaft (System.Diagnostics) 1. Lösungsvorschlag: Umfasse den Abruf mit einem try-catch und logge, wenn ein Prozess nicht abgerufen werden konnte. 2. Lösungsvorschlag: Du rufst nur die Prozesse ab, die keine "Pseudoprozesse" sind, mit: foreach (var p in Process.GetProcesses().Where(x=>x.StartInfo.UseShellExecute==false).ToList()) { ... } Verdammt. Habs grad selbst debuggt und gesehen, dass der "System" prozess mit der PID 4 das Problem auslöst. Auf die ID kann ich zugreifen, nicht aber auf attribute des mainmodules. Das Problem mit 32 und 64 bit habe ich, meines erachtens nach, schon gelöst. Hatte das problem in der anfangszeit und hab dann meinen dienst so kompiliert, dass er das schafft (x86/x64). Wenn ich dein "foreach (var p in Process.GetProcesses().Where(x=>x.StartInfo.UseShellExecute==false).ToList())" benutze, werden dann auch wirklich nur die pseudoprozesse geblockt oder können da auch noch andere prozesse geblockt werden, die nur anders gestartet werden? Hätte sonst die idee, alles unter PID 50 zu blocken, aber wenn deine zeile auch klappt, wäre das natürlich eleganter Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 Ja. Binde LINQ ein: using System.Linq; und verändere dein foreach Statement nach: foreach (Process p in Process.GetProcesses().ToList()) Das ist übrigens totaler Quatsch und macht keinen Sinn. foreach benötigt nur, dass der Typ IEnumerable implementiert. LINQ ist wiederum nur ein Satz Extension Methods auf IEnumerable. Was du an der Stelle machst, ist eine recht teure Operation (.toList()) auf ein IEnumerable, von der du im weiteren keine Vorteil hast. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
David1993 Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 Verdammt. Habs grad selbst debuggt und gesehen, dass der "System" prozess mit der PID 4 das Problem auslöst. Auf die ID kann ich zugreifen, nicht aber auf attribute des mainmodules. Das Problem mit 32 und 64 bit habe ich, meines erachtens nach, schon gelöst. Hatte das problem in der anfangszeit und hab dann meinen dienst so kompiliert, dass er das schafft (x86/x64). Wenn ich dein "foreach (var p in Process.GetProcesses().Where(x=>x.StartInfo.UseShellExecute==false).ToList())" benutze, werden dann auch wirklich nur die pseudoprozesse geblockt oder können da auch noch andere prozesse geblockt werden, die nur anders gestartet werden? Hätte sonst die idee, alles unter PID 50 zu blocken, aber wenn deine zeile auch klappt, wäre das natürlich eleganter In der MSDN Doku steht weiter unten folgender Hinweis: Ein Prozessmodul stellt eine DLL- oder EXE-Datei dar, die in einen bestimmten Prozess geladen wird. Die MainModule-Eigenschaft ermöglicht das Anzeigen von Informationen über die zum Starten des Prozesses verwendete ausführbare Datei, einschließlich des Modulnamens, des Dateinamens und der Informationen über den Modulspeicher. Hinweis zu : Diese Eigenschaft ist auf dieser Plattform nicht verfügbar, wenn beim Starten des Prozesses ProcessStartInfo.UseShellExecute auf true festgelegt ist. Damit müsste es meiner Meinung nach funktionieren. Teste es am Besten aus. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 In der MSDN Doku steht weiter unten folgender Hinweis: Damit müsste es meiner Meinung nach funktionieren. Teste es am Besten aus. Hab jetzt if (p.StartInfo.UseShellExecute == false) {...} Und jetzt überspringt er alle prozesse bis auf den, wo es den fehler gibt xD Werd's jetzt mal umgekehrt abfragenm also auf true, und gucken, ob es dann klappt. Wenns nicht geht, nehm ich deinen try-catch vorschlag (geht ja auch). Danek schonmal, ich meld mich dann gleich Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 Also mit der true-sache geht es auch net. Dann werden zwar wieder die prozesse genommen, aber eben auch der pseudoprozess. Ich versuch's jetzt erstmal mit dem try-catch-konstrukt Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 Tschuldigung, noch eine weitere Frage: Macht es sinn einen try-catch block in einem try-catch-block zu haben? In meinem anfangscode seht ihr ja, dass in der mitte schon ein try-catch ist. Ich benutze diese konstrukte nicht zum fehleranalysieren sondern nur zum auffangen von fehlern. Reicht es von daher, wenn ich einen übergeordneten try-catch block nehme? Oder kann es sein, dass z.b. unteraufrufe o.ä. nochmal einen eigenen try-catch block brauchen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 5. September 2013 Teilen Geschrieben 5. September 2013 try catch sollte nur sehr bewußt und nur sehr dezent eingesetzt werden. Schon gar nicht sollte man damit rechnen, dass ein Fehler fliegt. Du möchtest das Ursprungsproblem beheben. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
XspYroX Geschrieben 5. September 2013 Autor Teilen Geschrieben 5. September 2013 *gelöscht*, sorry für den doppelpost Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
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.