Mit einem C# Konsole Programm abwechselnd zwei Browser in den Vordergrund holen.



  • Heya!

    
    
    Process chrome_process = Process.Start("chrome.exe");  // OK wird aufgerufen und in den Vordergrund gebracht
               IntPtr chrome_hWnd = chrome_process.MainWindowHandle;
               Thread.Sleep(15000);
    
               Process opera_process = Process.Start("opera.exe"); // OK wird aufgerufen und in den Vordergrund gebracht
               IntPtr opera_hWnd = opera_process.MainWindowHandle;
               Thread.Sleep(15000);
    
               // Nun soll Chrome wieder im Vordergrund sein(danach wieder Opera usw).
               SetForegroundWindow(chrome_hWnd); // NICHT OK!!!!! Opera bleibt im Vordergrund. F U C K !!!!
    

    Wer weiß wie das geht?



  • Schau dir mal die Werte von chrome_hWnd und opera_hWnd an und dann Process.Refresh(). Du gibst den Prozessen auch keine Zeit ein Fenster zu basteln bevor Du die Eigenschaft MainWindowHandle kopierst.

    using System;
    using System.Threading;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace csfun
    {
        class Program
        {
            [DllImport("user32.dll")]
            static extern bool SetForegroundWindow(IntPtr hWnd);
    
            static void Main(string[] args)
            {
                Process charmap = Process.Start("charmap.exe");
                Process notepad = Process.Start("notepad.exe");
    
                charmap.WaitForInputIdle();
                notepad.WaitForInputIdle();
    
                for (;;) {
                    charmap.Refresh();
                    SetForegroundWindow(charmap.MainWindowHandle);
                    Thread.Sleep(1000);
    
                    notepad.Refresh();
                    SetForegroundWindow(notepad.MainWindowHandle);
                    Thread.Sleep(1000);
                }
            }
        }
    }
    


  • Mit charmap.exe und notepad.exe funzt dein Beispiel super. Mit den Browsern aber nicht.

                for (; ; )
                {
                    chrome_process.Refresh();
                    SetForegroundWindow(chrome_process.MainWindowHandle);
                    Thread.Sleep(3000);
    
                    opera_process.Refresh();
                    SetForegroundWindow(opera_process.MainWindowHandle); (1*)
                    Thread.Sleep(3000);
                }
    

    (1*) "System.InvalidOperationException: "Die angeforderten Informationen sind nicht verfügbar, da der Prozess beendet wurde."

    Beide Browser liefen aber noch.



  • Das wird an der seit einiger Zeit üblichen Praxis von Browsern zu liegen für diverse Aufgaben mehrere Prozesse zu starten. Eine Möglichkeit wäre Process.GetProcessesByName() und die zurückgegebenen Prozesse nach einem geeigneten Fenster abklopfen.



  • Werd ich ausprobieren, danke.



  • Ist aber schon iwie beknackt ein Handle(opera_process.MainWindowHandle) auf einen Prozess zu bekommen, der danach stirbt? Danach muss man den "richtigen" Prozess in einer Schleife rauspopeln? Geht das vllt. iwie einfacher? dummguck.



  • du könntest ja einfach alle fenster in den vordergrund holen und die exceptions verwerfen.🙄

    aber was diejenige person, die sich das ausgedacht hat, abends so in ihre pfeife steckt, möchte ich auch gerne mal wissen.😃



  • Mir ist gerade aufgefallen, dass beide Browser noch laufen und dennoch kommt die Meldung:

    "System.InvalidOperationException: Die angeforderten Informationen sind nicht verfügbar, da der Prozess beendet wurde."
    

    Immerhin bin ich der Meinung, dass ich mir mit das Handle auf das Hauptfenster hole mit

    IntPtr opera_hWnd = opera_process.MainWindowHandle;
    

    Warum quakt dann der Compiler der Prozess(das Hauptfenster) sei beendet worden, wenn es doch ganz klar zu sehen ist?



  • weißt du eigentlich, was prozesse, mainwindows und nicht-mainwindows (aka childwindows) sind?



  • Wieso die Frage, wenn ich ein Handle aufs Hauptfenster bekomme, erwarte ich, dass es solange gültig ist, wie das Fenster sichtbar ist. Bzw. solange der Browser läuft. Bzw. solange der Browser läuft.



  • Mit Swordfischs Vorschlag bekomme ich 9 Chrome-Prozesse, obwohl ich Chrome nur einmal starte. verdammte Frickelei
    Wie bekomme ich nun heraus, welches das "geeignete Fenster" ist? Ich möchte doch bloß den Browser in den Vordergrund holen.



  • Einfach für alle 9 Prozesse SetForegroundWindow aufrufen? xD



  •  while(true)
                {
                    Process[] processName = Process.GetProcessesByName("chrome");
                    if (processName.Length != 0)
                    {
                        foreach(Process proc in processName)
                        {
                            Console.WriteLine(proc.ProcessName);
                            Stuff.SetForegroundWindow(proc.MainWindowHandle);
                        }
                        chrome_process.WaitForInputIdle();
                    }
    
                    Thread.Sleep(3000);
    
                    processName = Process.GetProcessesByName("opera");
                    if (processName.Length != 0)
                    {
                        foreach (Process proc in processName)
                        {
                            Console.WriteLine(proc.ProcessName);
                            Stuff.SetForegroundWindow(proc.MainWindowHandle);
                        }
                        opera_process.WaitForInputIdle();
                    }
    
                    Thread.Sleep(3000);
    }
    

    Das gibt dieselbe Meldung. schnief



  • @bruder sagte in Mit einem C# Konsole Programm abwechselnd zwei Browser in den Vordergrund holen.:

    Wieso die Frage, wenn ich ein Handle aufs Hauptfenster bekomme, erwarte ich, dass es solange gültig ist, wie das Fenster sichtbar ist. Bzw. solange der Browser läuft. Bzw. solange der Browser läuft.

    naja wenn du die frage mit "ja, ja und ja" beantworten könntest, würde deine erwartung vielleicht anders aussehen.

    @bruder sagte in Mit einem C# Konsole Programm abwechselnd zwei Browser in den Vordergrund holen.:

    Mit Swordfischs Vorschlag bekomme ich 9 Chrome-Prozesse, obwohl ich Chrome nur einmal starte. verdammte Frickelei
    Wie bekomme ich nun heraus, welches das "geeignete Fenster" ist? Ich möchte doch bloß den Browser in den Vordergrund holen.

    vermutung: alle anderen 8 prozesse haben kein fenster, und deshalb schlägt SetForegroundWindow fehl bzw. wirft die ausnahme.
    aber wie gesagt: ich weiß auch nicht, was die sich dabei gedacht haben, so viele prozesse zu starten. irgendwer hat das halt mal entschieden und alle anderen haben abgenickt. 😃

    @bruder sagte in Mit einem C# Konsole Programm abwechselnd zwei Browser in den Vordergrund holen.:

    Das gibt dieselbe Meldung. schnief

    weißt du eigentlich, was eine ausnahme bzw. exception ist?



  • Astatt meine mageren Kenntnisse mit Fragen bloßszustellen könntest du mir ja lieber verraten, wie ich das zum Laufen bekomme 😉
    Okay ich versuche mal was mit try/catch 🙂



  • Ich nehme an, Ausnahmen bestätigen die Regel oder wie war das.
    Okay die Exceptions dienen als eine quasi Sicherheitsmaßnahme dazu, um das Programm/Betriebssystem vor Crahs zu schützen. vermut



  • Der Grund ist ganz einfach: wenn ein Tab abstürzt (=> Prozess wird gekillt), sind nicht gleich alle anderen Tabs auch weg.
    Es sollte trotzdem immer einen Hauptprozess (mit dem Hauptfenster) geben.

    Zumindestens beim Firefox gibt es nur ein Hauptfenster und die anderen Prozesse (welche per "-contentproc" gestartet werden) haben kein Fenster - sieht man gut mit dem Process Explorer).



  • @bruder sagte in Mit einem C# Konsole Programm abwechselnd zwei Browser in den Vordergrund holen.:

    Astatt meine mageren Kenntnisse mit Fragen bloßszustellen könntest du mir ja lieber verraten, wie ich das zum Laufen bekomme 😉

    du könntest ja auch versuchen, dir das zur beantwortung dieser fragen notwendige wissen anzueignen (viel wissen ist immer gut) und dann würdest du ja auch wissen, dass prozesse voneinander unabhängige programme sind und daher nichts mit dem hauptfenster vom firefox zu tun haben müssen.

    Okay ich versuche mal was mit try/catch 🙂

    du könntest ja auch mal im debugger gucken, ob der handle einen gültigen wert (ich glaube irgendwas größer 0) besitzt bzw. inwiefern sich die handles voneinander unterscheiden.



  • Ich habe nu den Code unten probiert, es lief ca. 1 Minute ohne Absturz, das ist doch schon mal etwas. Könnte mir vll. jemand mal sagen, wie ich das verbessern könnte? Diese foreach Schleifen finde ich nicht dolle, kommt mir schon fast wie eine Brute-Force-Methode vor um ein Fensterchen in den Vordergrund zu bekommen. Und die leeren Catch-Blöcke gefallen mir auch nicht oder kann man den Code so lassen?

    Process chrome_process;
                Process opera_process;
    
                try
                {
                    chrome_process = Process.Start("chrome.exe");
                    opera_process = Process.Start("opera.exe");
                    chrome_process.WaitForInputIdle();
                    opera_process.WaitForInputIdle();
                } catch (Exception e) { }
    
                Thread.Sleep(3000);
    
                while(true)
                {
                    Process[] processName = Process.GetProcessesByName("chrome");
                    if (processName.Length != 0)
                    {
                        foreach (Process proc in processName)
                        {
                            try
                            {
                                Console.WriteLine(proc.ProcessName);
                                Stuff.SetForegroundWindow(proc.MainWindowHandle);
                            }
                            catch (Exception e) { }
                        }
                    }
    
                    Thread.Sleep(3000);
    
                    processName = Process.GetProcessesByName("opera");
                    if (processName.Length != 0)
                    {
                        foreach (Process proc in processName)
                        {
                            try
                            {
                                Console.WriteLine(proc.ProcessName);
                                Stuff.SetForegroundWindow(proc.MainWindowHandle);
                            }
                            catch(Exception e){}
                        }
                    }
                    Thread.Sleep(3000);
                }
    


  • @Wade1234 "dann würdest du ja auch wissen, dass prozesse voneinander unabhängige programme sind und daher nichts mit dem hauptfenster vom firefox zu tun haben müssen."
    Ja, das wusste ich aber dann sollen die Browser-Entwickler doch bitte die Prozesse anders benennen, die nix mit dem Hauptfenster zu tun haben. 😃


Log in to reply