Zum Inhalt springen

Code nach foreach-schleife wird nicht ausgeführt


XspYroX

Empfohlene Beiträge

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 >_>

Link zu diesem Kommentar
Auf anderen Seiten teilen

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^^"

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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^^"

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 von David1993
Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

:)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...