Laden...

F5-Tastendruck an den Prozess 'chrome.exe' senden?

Erstellt von vwtyluqhuy vor 2 Jahren Letzter Beitrag vor 2 Jahren 672 Views
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren
F5-Tastendruck an den Prozess 'chrome.exe' senden?

Hallo zusammen

folgender Code liegt vor, funktioniert allerdings nicht. (Quelle: simulating-key-press-c-sharp ):


using System;

using System.Linq;



using System.Diagnostics;
using System.Management;
using System.Runtime.InteropServices;
using System.Threading;

namespace SendKeyPress
{
    class Program
    {
        private static string lChromeProcessNameWithExtension = "chrome.exe";

        private static string mExecutablePath = "C:/Program Files/Google/Chrome/Application/" + lChromeProcessNameWithExtension;

        private static bool lUseChromium = true;

        static Program()
        {
            if(lUseChromium)
            {
                mExecutablePath = "C:/Users/user1/AppData/Local/Chromium/Application/" + lChromeProcessNameWithExtension;
            }
        }        

        private static String convertToWindowsPathFormat(string str)
        {
            str = str.Replace("/", "\\");
            return str;
        }

        private static void writeEmpyLine()
        {
            Console.Write("\r\n");
        }

        private Program(string[] args)
        {
            if(args[0].Trim().Length == 0)
            {
                Console.WriteLine("URL was not set...");
                return;
            }

            mExecutablePath = Program.convertToWindowsPathFormat(Program.mExecutablePath);

            string lParameters = args[0];

            string lExecutablePathWithParameters = mExecutablePath + " " + lParameters;

            writeEmpyLine();

            Console.WriteLine("Command line: " + lExecutablePathWithParameters);
           
            /////////////////////////////////////////////////////////////////////
            Process[] lProcessArr = Program.getProcesses();
            
            string lChromeProcessName = lChromeProcessNameWithExtension.Substring(0, lChromeProcessNameWithExtension.Length - 4);

            Boolean lProcessIsStarted = false;

            Process lProcess = null;

            for (int lCnt = 0; lCnt < lProcessArr.Length; lCnt++)
            {
                lProcess = lProcessArr[lCnt];
                string lProcessName = lProcess.ProcessName;

                if (lProcessName.Contains(lChromeProcessName))
                {
                    string lProcessExecutablePath = Program.getProcessPath(lProcess.Id);

                    if (lProcessExecutablePath.Equals(mExecutablePath))
                    {
                        lProcessIsStarted = !lProcessIsStarted;

                        if (lProcessIsStarted)
                        {
                            break;
                        }
                    }                       
                }

            }
            /////////////////////////////////////////////////////////////////////

            writeEmpyLine();            

            if (!lProcessIsStarted)
            {
                Program.startProcess(args);
            }
            else
            {
                string lProcessExecutablePath = Program.getProcessPath(lProcess.Id);               

                if (lProcessExecutablePath.Equals(mExecutablePath))
                {
                    Console.WriteLine("Process '" + lChromeProcessNameWithExtension + "' is already started - do a website refresh...");
                    ProcessControl.sendKeyPress(lProcess.Id);
                }
                else
                {
                    Program.startProcess(args);
                }
            }
        }

        private static void startProcess(String[] args)
        {
            Console.WriteLine("Process '" + lChromeProcessNameWithExtension + "' is not started yet - will start now...");
            Process.Start(mExecutablePath, args[0]);
        }

        private static Process[] getProcesses()
        {
           return Process.GetProcesses();
        }

        static void Main(string[] args)
        {
            if(args == null)
            {
                args = new string[0];
            }

            if(args.Length == 0)
            {
                Console.WriteLine("No command line parameters set");
                return;
            }

            new Program(args);
        }




        private static string getProcessPath(int processId)
        {
            string MethodResult = "";

            try
            {
                string Query = "SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;

                using (ManagementObjectSearcher mos = new ManagementObjectSearcher(Query))
                {
                    using (ManagementObjectCollection moc = mos.Get())
                    {
                        string ExecutablePath = (from mo in moc.Cast<ManagementObject>() select mo["ExecutablePath"]).First().ToString();
                        MethodResult = ExecutablePath;
                    }

                }

            }
            catch (Exception lException)
            {
                Console.WriteLine(lException.Message);
            }

            return MethodResult;
        }
    }
}

static class ProcessControl
{
    const UInt32 WM_KEYDOWN = 0x0100;
    const int VK_F5 = 0x74;

    [DllImport("user32.dll")]
    static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

    [STAThread]
    public static void sendKeyPress(int processID)
    {
        // Console.WriteLine(processID);
        Process proc = Process.GetProcessById(processID);            
        PostMessage(proc.MainWindowHandle, VK_F5, VK_F5, 0);                                
    }
}

Weiss jemand weiteres zum Thema? Könnte es evtl. daran liegen, dass das Fenster von 'chrome.exe' (Chrome oder Chromium) nicht fokussiert ist? Besten Dank für die Feedbacks.

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Oder könnte es sein, dass das obere Beispiel (unter simulating-key-press-c-sharp ) doch das "bessere" (m.E. eher weniger?) ist?


static class Program
{
    [DllImport("user32.dll")]
    public static extern int SetForegroundWindow(IntPtr hWnd);

    [STAThread]
    static void Main()
    {
        while(true)
        {
            Process [] processes = Process.GetProcessesByName("iexplore");

            foreach(Process proc in processes)
            {
                SetForegroundWindow(proc.MainWindowHandle);
                SendKeys.SendWait("{F5}");
            }

            Thread.Sleep(5000);
        }
    }
}

(Natürlich ohne die Schleife für meinen konkreten Anwendungsfall...😉)

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren
Hinweis von Abt vor 2 Jahren

Keine externen Bildhoster
[Hinweis] Wie poste ich richtig?

FRAGE: Wie kann ein Prozess (als .exe-Datei) nur 1x gestartet sein, aber mehrere Prozess-IDs inne haben?

// Edit: Bild entfernt

P.S.: Und wie fügt man hier [externe] Bilder ein??

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Ich meine HIER wird's relativ offensichtlich, dass chrome.exe nur 1x gestartet ist - ganz im Ggs. zum anderen rot markierten Prozess...

Et volià:Edit: Bild entfernt.

Hinweis von Abt vor 2 Jahren

Keine externen Bildhoster
[Hinweis] Wie poste ich richtig?

Gruss, Franz
M
368 Beiträge seit 2006
vor 2 Jahren

funktioniert allerdings nicht.

Testsystem: Windows 10 Pro, .NET 5.0 Runtime, VS Comm. 2019 Der Testcode funktioniert -naiv kompiliert und mit @ vor der Pfadangabe- jedenfalls.


...        mExecutablePath =@"C:/Program Files/Google/Chrome/Application/" + lChromeProcessNameWithExtension;

Weiterhin kann man in die Kommandozeile gehen und ruft das kompilierte Programm zu Fuss auf (Anhang)

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Hallo M.L.

Vielen Dank für das schnelle Feedback! 🙂

Bei mir will es noch nicht so ganz - deshalb noch 2 Fragen:

1.) Was bedeutet das ´@´ vor dem String?

2.) Verstehst du unter "naiv kompiliert" wohl eher "nativ kompiliert" was heisst als CPU-Plattform nicht mehr "any", sondern "x64" (oder ggf. x86) zu wählen?

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

@Jamikus: Danke!

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

**Nachtrag: **Da ich https://github.com/Zoomicon/SpeechLib verwende, muss ich leider noch auf dem 4.x-Framework bleiben... wie mir aufgefallen ist, kann VS 2019 für Anwendungen nur noch .NET Core / 5.0-Anwendungen generieren. (Scheint aber nicht für Assemblies zu gelten - mit VS 2019 kann man immer noch z.B. für das .NET Framework 4.x Assemblies erstellen - frage mich gerade, ob dies nur für die Express-Version gilt oder ob dem generell so sei - halt auch bei den kostenpflichtigen Versionen...?)

Alles in allem geht es darum: Es soll eine Sprachsteuerung erstellt werden, welche a.) Über ein vordefiniertes "Initialwort" mithilfe von GitHub - Zoomicon/SpeechLib: Library for Speech Synthesis and Recognition using Windows.Speech or Microsoft.Speech and optionally Kinect V1 Sensor Microphone Array den Browser mit einer best. URL startet, oder, falls dieser bereits gestartet ist, einen Browser-Refresh veranlasst (darum geht's ja im Thread)... nach dem Start oder Refresh der Browsers wird ein Client-seitiger Code aufgerufen, welcher die Browser-Sprachsteuerung (mithilfe von GitHub - TalAter/annyang: Speech recognition for your site ) in Gang setzt. (GitHub - TalAter/annyang: Speech recognition for your site in einer Endlos-Schleife zu starten funktioniert nicht wirklich, scheint "non-blocking" zu sein was das Ganze drunter und drüber geraten lässt) Wenn der Browser mithilfe dieses JS-Codes dann ein Wort erkannt hat, soll er einen Webservice per AJAX (oder SJAX?) aufrufen in der Art http://localhost/speechservice.php?word=ERKANNTES_WORT

Gruss, Franz
T
2.219 Beiträge seit 2008
vor 2 Jahren

Du kannst auch in anderen Versionen mit .NET Framework arbeiten.
Selbst in VS 2022 kannst du das noch.
Das wird auch vermutlich noch einige Versionen lang supportet.

Mit Express o.ä. hat das nicht viel zu tun.
Liegt einfach daran, dass .NET Framework halt noch supportet wird seitens MS.
Auch wenn .NET 5/6 die bessere Wahl sind, wird auch MS nicht übernacht für ein supportetes Produkt alles absägen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

-> Vielleicht (NUR "vielleicht"?) könnte man GitHub - Zoomicon/SpeechLib: Library for Speech Synthesis and Recognition using Windows.Speech or Microsoft.Speech and optionally Kinect V1 Sensor Microphone Array auch für das Core / 5.0-Framework kompilieren - dessen bin ich mir aber nicht 100% sicher und bleibe aus diesem Grund mal lieber bei v4.0...

Gruss, Franz
T
2.219 Beiträge seit 2008
vor 2 Jahren

Warum 4.0?
Das dürfte schon lange abgekündigt sein bzw. hat keinen Support mehr von MS.
Spring lieber erstmal auf 4.8, dass wird vermutlich noch ein paar Jahre support haben.
Dann kannst du auch ohne Probleme deine .NET 4.0 Verweise etc. verwenden.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

@T-Virus: M.E. nicht wirklich: Edit: Bild entfernt.

Konsolenanwendung: "[...] die mit .NET Core unter [...]"

Klassenbibliothek: "[...] für .NET Standard oder .NET Core"

...aber wer weiss, vielleicht ist dies bei VS 2022 wieder anders?

Und die 4.x-Version habe ich ja extra geladen damit ich bei VS 2017 Express unter dem Projekteinstellungen die Version 4.8 wählen kann.

EDIT: "Warum 4.0?"

Sry. meinte 4.x... konkret 4.8 😉

Hinweis von Abt vor 2 Jahren

Keine externen Bildhoster
[Hinweis] Wie poste ich richtig?

Gruss, Franz
M
368 Beiträge seit 2006
vor 2 Jahren

2.) Verstehst du unter "naiv kompiliert"

Zus. zu 1.): im konkreten Fall braucht man @ nicht, aber längerfristig ist es die solidere Entscheidung
2.) das "t" fehlt absichtlich: VS starten, WinForms-Projekt anlegen, Program.cs öffnen, gegebenen Quellcode kopieren, "Debug" und "Any CPU" belassen, alles speichern, Run-Button. Und kurz danach auf der Kommadozeile mit geöffnetem (oder geschlossenem) Chromebrowser experimentieren (<- evtl. waren andere Vorgehensweisen geplant)

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Danke werde mal schauen... geplant wäre eher ein Dienst, welcher im Hintergrund läuft. In Form einer Konsolenanwendung in welcher sich ne Endlosschleife "dreht". Diese soll z.B. mit https://nssm.cc/ zu einem Dienst gemacht werden

Gruss, Franz
T
2.219 Beiträge seit 2008
vor 2 Jahren

@vwtyluqhuy
Dann scheinst du nicht richtig zu gucken bzw. scroll doch mal runter.
Die ganzen Projekte für Framework haben i.d.R. ein "(.NET Framework)" im Namen.
Kann ich sowohl in VS 2019 als auch 2022 sehen und auswählen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Oh ja, vielen Dank!! 🙂

(Trotzdem bleibe ich an dieser Stelle mal lieber bei 4.8 wegen der SpeechLib-Assembly von GitHub [welche soweit auch läuft und auf das Initialwort hört]... will mir aktuell nicht noch mehr Probleme schaffen...)

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Zwischenfrage: Habe mir jetzt mal mit VS 2019 Express eine .NET 4.8-GUI-Anwendung erstellt und nun festgestellt, dass zwar die "MessageBox" funktioniert, nicht aber Console.Write[...]:


       private void button1_Click(object sender, EventArgs e)
        {            
            Console.WriteLine("test"); // DOES NOT WORK!!
            MessageBox.Show("title", "text");  // WORKS!!
        }

Die obere Zeile verursacht

a.) Weder einen Absturz zur Laufzeit

NOCH

b.) Eine sonstige Reaktion

-> Es passiert einfach gar nichts dabei. Kommt bei einer 4.8-GUI-Anwendung die Console-Klasse gar nicht mehr zum Einsatz? Ich erinnere mich an früher als ich ein paar mal mit .NET was gemacht habe (war noch vor 2010), damals (Versionen 2.0 / 3.5) machte die Console-Klasse noch was bei einer GUI-Anwendung. Ist dies Heute scheinbar nicht mehr der Fall?

Gruss, Franz
D
261 Beiträge seit 2015
vor 2 Jahren

Was erwartest du denn bei einem Console.WriteLine wenn du eine GUI offen hast?
Wenn du in die Debug Console von VS schreiben willst, musst du Debug.WriteLine verwenden.

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Danke fürs Feedback.

"Was erwartest du denn bei einem Console.WriteLine wenn du eine GUI offen hast?"__

Dass wenn ich die Anwendung mit** cmd.exe** starte, dass mir dann was in die Konsole geloggt wird. (In meinem Fall, wenn ich auf den Button drücke -> onClick-Event halt)

Wenn ich mich nicht täusche (???) so ging das früher mal. Aber nun scheint sich dies plötzlich geändert zu haben, richtig?

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Ne, geht leider genauso wenig wie "Console...":


private void button1_Click(object sender, EventArgs e)
        {
            Debug.WriteLine("test");
            // Console.WriteLine("test"); // DOES NOT WORK!!
            // MessageBox.Show("title", "text");  // WORKS!!
        }

Kann sonst ein Video aufzeichnen Zwecks Beweis... 😉

Gruss, Franz
vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

-> Build ist "Debug", nicht "Release"...

Und auch in der PowerShell-Konsole seh ich rein gar nix... 😉

Gruss, Franz
D
261 Beiträge seit 2015
vor 2 Jahren

Ich rede vom Output Fenster in Visual Studio wenn du die Anwendung über Visual Studio startest. Dort funktioniert es mit folgendem Code:


private void button1_Click(object sender, EventArgs e)
        {
            Console.WriteLine("test");
            Debug.WriteLine("test2");
        }

Ergebnis: siehe Anhang

Für die PowerShell bzw. cmd musst du den "Output type" deiner Anwendung auf "Console Application" stellen.
Rechtsklick aufs Projekt -> Properties -> Application -> Output type

Es öffnet sich dann aber auch ein zusätzliches Konsolenfenster wenn du die Anwendung per Doppelklick startest.
Edit: Ob es noch andere Nachteile gibt, musst du selbst recherchieren.

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Vielen Dank... oha, wie das alles kompliziert geworden ist... vor ca. 10 Jahren konnte ich (ursprünglich Java-Entwickler) noch rein intuitiv vorgehen bei .NET - insbesondere bei C# wegen der Syntax. (Mittlerweile sind aber auch viele neue Sprachelemente hinzugekommen, welche sich klar von Java abgrenzen...)

Gruss, Franz
M
368 Beiträge seit 2006
vor 2 Jahren

alles kompliziert geworden ist...

(teilweise offtopic) Der gezeigte Quellcode funktioniert auch ohne Umwege über z.B. PowerShell oder zusätzliche (ältere) Befehle, siehe Anhang.
Im Gegensatz zu Java nimmt .NET aber nicht unbedingt auf Plattformkompatibilität Rücksicht. Es kann also passieren, dass man auf Codes oder Vorgehensweisen trifft, die damals möglich (wenn auch nicht zwingend sinnvoll) waren. Aber diese sind angesichts neuerer Änderungen, Entwicklungen, Erweiterungen,... obsolet (geworden), bekanntere Beispiele sind "(Un)Boxing" vs. "Generics" oder der neue(re) Umgang mit Zeiten.

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

vwtyluqhuy Themenstarter:in
17 Beiträge seit 2022
vor 2 Jahren

Danke fürs Feedback.

Ja, ist halt nicht immer alles trivial. Aber was will man machen - dran bleiben lautet die Devise.

"Im Gegensatz zu Java nimmt .NET aber nicht unbedingt auf Plattformkompatibilität Rücksicht."****

Ja, das hat aber auch seine Vorteile - OS-API-Sachen zu machen geht dann einiges einfacher als bei Java.

BTW ist mir irgendwo (VS 2019 oder auch schon bei 2017?) dass mir der Code-teil, der nicht Plattform-unabhängig ist, entsprechend markiert wurde. (Wenn ich mich nicht täusche bei der Speech-Library und bei der Prozesssteuerung?)

Gruss, Franz