Laden...

Prozessprüfung 32 und 64 Bit von 32 Bit Applikation

Erstellt von Pioneer17 vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.534 Views
P
Pioneer17 Themenstarter:in
148 Beiträge seit 2007
vor 12 Jahren
Prozessprüfung 32 und 64 Bit von 32 Bit Applikation

Hallo zusammen

ich habe da immer noch ein etwas grösseres Problem mit Prozessen unter 32- und 64 Bit. Ich habe versucht eine zuverlässige Methode zu erstellen mit welcher ich egal ob ich auf einem 32- oder 64 Bit System arbeite Prozesse (32- und 64 Bit) den Zustand zu prüfen und ggf. auch wieder neu starten.

Evtl. habe ich das jetzt einbisschen kompliziert beschrieben, ist das Vorhaben eigentlich ganz simpel - jedoch die Umsetzung funktioniert noch nicht so zuverlässig.

in den beiden Beiträgen Name und Pfad (der EXE) eines fremden laufenden Prozesses ermitteln und Exception bei Process.MainModule.Filename unter Win 7 64 Bit habe ich diese Problematik bereits mal angesprochen. Nun aber bin ich zwar weiter gekommen jedoch glaube ich auf eine sehr umständliche Art und Weise.

Was habe ich gemacht:
Zuerst befülle ich ein Dictionary<string, ProcessInfo> AppEventHandler mit den zu überwachenden Applikationen.
in diesen AppEventHandler ist der Key der komplette Programmpfad (z.B. c:\windows\system32\calc.exe) und die Values jeweils die ProcessInfo dazu
z.B.


ProcessInfo App = null; // separate Klasse
for (int i = 0; i < Service1.Applikationen.Count; i++) // Da sind die verschiedenen zu überwachenden Pfade drin
{
    if (!Service1.AppEventHandler.ContainsKey(Path.GetFileName(Service1.Applikationen[i])))
    {
        try
        {
            App = new ProcessInfo(Path.GetFileName(Service1.Applikationen[i]));
            App.Started += new ProcessInfo.StartedEventHandler(Service1.ProcessStarted);
            App.Terminated += new ProcessInfo.TerminatedEventHandler(Service1.ProcessTerminated);
            Service1.CheckAppWMIStart(Service1.Applikationen[i]); // siehe Codeblock unten
            Service1.AppEventHandler.Add(Path.GetFileName(Service1.Applikationen[i]), App);
        }
        catch (Exception ex)
        {
            // Fehlermeldung ausgeben
        }
    }
}

In dieser Methode hole ich mir die dazugehörige Prozess-ID weil ich mit meinem 32-Bit Porgramm nicht direkt über ProcessInfo auf 64-Bit Prozesse zugreiffen kann.


	public static void CheckAppWMIStart(string Applikation)
        {
            Applikation = Applikation.Remove(0, 1);
            DataTable processList = ProcessInfo.RunningProcesses();
            for (int i = 0; i < processList.Rows.Count; i++)
            {
                object[] r = processList.Rows[i].ItemArray;
                if (r[0].ToString().ToLower() == Path.GetFileName(Applikation).ToLower())
                {
                    if (!Appl.Contains(r[3].ToString().ToLower()))
                    {
                        Appl.Add(r[3].ToString().ToLower()); //Prozess-ID
                    }
                }
            }
        }

Und schlussendlich die eigentlichen Eventhandler:


        public static void ProcessStarted(object sender, EventArgs e)
        {
            EventArrivedEventArgs ee = e as EventArrivedEventArgs;
            string TIExecutablePath = ((ManagementBaseObject)ee.NewEvent["TargetInstance"])["ExecutablePath"].ToString().ToLower();
            if (!Appl.Contains(TIExecutablePath))
            {
                Appl.Add(TIExecutablePath);
            }
        }

        public static void ProcessTerminated(object sender, EventArgs e)
        {
            EventArrivedEventArgs ee = e as EventArrivedEventArgs;
            string TIExecutablePath = ((ManagementBaseObject)ee.NewEvent["TargetInstance"])["ExecutablePath"].ToString().ToLower();
            if (Appl.Contains(TIExecutablePath))
            {
                Appl.Remove(TIExecutablePath);
            }
        }

Es ist rel. ein komplizierte Art und Weise das so zu prüfen und vor Allem eben Fehleranfällig. Teilweise wird der Event "ProcessTerminated" für ein Prozess welcher geschlossen wird nicht ausgelöst und somit bekomme ich das Programmende nicht mit.

Grundsätzlich habe ich die Frage ob es nicht einen besseren Weg gibt Prozesse zu überwachen und neu zu starten. Wichtig ist, dass mein Programm fix in 32 Bit kompiliert ist und ich das nicht änderen kann.

Habe mit absicht nicht den kompletten Code gepostet, da es einerseits bestimmt verwirrend sein könnte und zum zweiten das teilweise gegen die Forenregeln verstösst. Sollte aber etwas an meinem Vorhaben unklar sein werde ich natürlich die Fehlenden Infos nachliefern.

Es ist mir bewusst, dass das sehr schwirig ist in Worte zu fassen, habe es einfach mal versucht. Danke für eure Hilfe.

G
538 Beiträge seit 2008
vor 12 Jahren

Mit der Tatsache, dass du aus einem x86-Programm auch x64-Programme überwachen willst schießt du dir meines Erachtens nach doch ziemlich ins Knie, denn abgesehen davon, dass du die ProcessInfo nicht direkt benutzen kannst, hast du auch auf bestimmte Ordner keinen direkten Zugriff, denn zum Beispiel "system32" landet aus einem x86 Prozess im Ordner "sysWOW64".
Einige Umgebungsvariablen sind auch anders - Microsoft war hier sehr bemüht transparent (im sinne von unsichtbar) die Kompatibilität zu x86 zu erhalten (leider - wie ich anmerken möchte).

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann - umgekehrt ist das schon schwieriger (K. Tucholsky)
Das Problem mit Internet-Zitaten ist, dass sie oftmals zu unrecht als authentisch angenommen werden. (K. Adenauer)

P
Pioneer17 Themenstarter:in
148 Beiträge seit 2007
vor 12 Jahren

Damit ich auf die "64-Bit" Ordner zugreiffen kann gibt es verschiedene Möglichkeiten - das funktioniert auch soweit.

Das ich mit aber ins Knie schiesse sehe ich nicht so. Es sollte ja nichts dabei sein verschiedene Prozesse zu überwachen. Ich kann einfach nicht auf die schnelle meine App mit Any CPU kompilieren, da div. Librarys dann nicht mehr funktioniere würden.

Mittels WMI gibt es ja Umwege um auf die 64-Bit Prozesse zuzugreiffen. Dabei habe ich nur das Probelm, dass der Windows Management Instrumentation Prozess (wmiprvse.exe) eine relativ hohe Auslastung hat. Der Prozess ist immer mit ca. 1-2 Prozenz beschäftigt, was ich erstaunlich viel finde. Dabei die Frage ob das "normal" ist?

Gibt es keinen Weg über die Windows API direkt auf die 64-Bit Prozesse zuzugreiffen? Irgendwie kann da ja WMI auch.