C#, Backgroundworker und SendKeys?

3 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Ein Beispiel, vielleicht hilft dir das weiter:

  1. Eine einfache Windows Forms Applikation anlegen.
  2. Textbox, Button und BackgroundWorker auf die Form ziehen.
  3. Button mit Klick-Event-Handler ausstatten.
  4. BackgroundWorker einen Handler für das DoWork-Event zuordnen.

Im Event-Handler des Buttons wird die Textbox fokusiert und der Worker gestartet:

textBox1.Focus();
backgroundWorker1.RunWorkerAsync();

Ein Delegate und eine dazu passende Methode werden definiert:

public delegate void Executor();

public void DoSomething()
{
  SendKeys.Send("Hello");
} 

Über das Delegate kann die Methode DoSomething nun gekapselt und an die Invoke-Methode übergeben werden. Das passiert im DoWork-Event-Handler. DoSomething wird also zur Ausführung im UI-Thread übergeben:

Invoke(new Executor(DoSomething));

verreisterNutzer  25.09.2018, 17:32

Das mit der Textbox habe ich schon mal probiert, hat nicht funktioniert. Könnte das vielleicht am Framework liegen?

0
verreisterNutzer  25.09.2018, 18:43
@regex9

Ne, habs so gemacht.

Hab erst auch versucht, einen Thread dafür zu erstellen, hab das aber nicht hingekriegt. Weisst du wie das geht? Kannst du das vorcoden pls?

0
regex9  25.09.2018, 22:34
@verreisterNutzer

Seltsam. Bei mir funktioniert das wunderbar.

Ein Beispiel mit Thread ist nicht großartig anders. Ich habe mir einen zweiten Button mit Klickhandler angelegt. In diesem wird das Textfeld fokusiert und der Thread (System.Threading) gestartet:

textBox1.Focus();
new Thread(() => Invoke(new Executor(DoSomething))).Start();
1
verreisterNutzer  26.09.2018, 08:34
@regex9

Ich möchte einen zweiten Thread erstellen, damit ich die laufende Aktion mit einem Button abbrechen kann. Würde das mit dem ersten Thread laufen, reagiert die Form ja nicht, während die Aktion noch läuft.

Wie würde ich denn diesen Thread in deinem Beispiel von einem Button aus stoppen?

0
regex9  26.09.2018, 09:27
@verreisterNutzer

Speichere dir den Thread in einem Feld und verwende die Methode Abort zum Stoppen.

1
verreisterNutzer  26.09.2018, 11:27
@regex9

Habe den zweiten Thread nun so erstellt:

static Thread t = new Thread(() =>
        {
          //Code
        }

Den Thread kann ich starten und stoppen, alles gut.

Aber gibt es eine Möglichkeit ohne grossen Umweg den Thread für 1 Sekunde anzuhalten?

t.Sleep(1000); geht nicht. Wenn ich Thread.Sleep(1000); mache wird ja der Hauptprozess pausiert.

0
regex9  26.09.2018, 18:49
@verreisterNutzer

Thread.Sleep innerhalb des Delegate blockiert den aktuellen Thread, der die Methode aufruft. Dies ist in dem Fall der von dir erstellte Thread. Alternativ dazu gibt es Thread.Delay. Lies hier für eine Erklärung beider Methoden.

1
verreisterNutzer  25.09.2018, 18:21

Gibt es eine Möglichkeit, einen Thread zu erstellen, der das macht und denn dann zu starten und zu stoppen? Funktioniert es damit besser?

0

Kann gut sein, dass es in deinem Falle nicht funktioniert (Timing-Anfälligkeit). Um mehr zu sagen müsste man deinen Code und dessen Umgebung kennen.

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys.send?view=netframework-4.7.2

The SendKeys class has been updated for the .NET Framework 3.0 to enable its use in applications that run on Windows Vista. The enhanced security of Windows Vista (known as User Account Control or UAC) prevents the previous implementation from working as expected. The SendKeys class is susceptible to timing issues, which some developers have had to work around. The updated implementation is still susceptible to timing issues, but is slightly faster and may require changes to the workarounds. The SendKeys class tries to use the previous implementation first, and if that fails, uses the new implementation. As a result, the SendKeys class may behave differently on different operating systems. Additionally, when the SendKeys class uses the new implementation, the SendWait method will not wait for messages to be processed when they are sent to another process.

If your application relies on consistent behavior regardless of the operating system, you can force the SendKeys class to use the new implementation by adding the following application setting to your app.config file.

<appSettings>

<add key="SendKeys" value="SendInput"/>

</appSettings>

To force the SendKeys class to use the previous implementation, use the value

"JournalHook"

instead.

Woher ich das weiß:Berufserfahrung – Studium der Informatik + Softwareentwickler seit 25 Jahren.

verreisterNutzer  24.09.2018, 19:39

Und wie wende ich das an?

0
Brainchild  24.09.2018, 19:43
@verreisterNutzer

Steht doch drin: In die xml-Datei app.config einfügen. Bevor du mir aber Löcher in den Bauch frägst, will ich Code sehen. Unqualifizierte Atworten liegen mir nicht. Will ja nicht raten.

0
verreisterNutzer  24.09.2018, 19:50
@Brainchild

Code:

if(zahl == 2)
            {
                //A
                //B
                //C
                //D
                //E
                //F
                //G
                //H
                //I
                //J
                //K
                //L
                //M
                //N
                //O
                //P
                //Q
                //R
                //S
                //T
                //U
                //V
                //W
                //X
                //Y
                //Z
                secThread.CancelAsync();
            }
            else if(zahl == 3)
            {
                //A
                //B
                //C
                //D
                //E
                //F
                //G
                //H
                //I
                //J
                //K
                //L
                //M
                //N
                //O
                //P
                //Q
                //R
                //S
                if (!leerzeichen.Checked)
                {
                    SendKeys.Send("ski {ENTER}");
                    Thread.Sleep(1000);                 
                }
                //T
                //U
                if (!leerzeichen.Checked)
                {
                    SendKeys.Send("usb {ENTER}");
                    Thread.Sleep(1000);
                }
                //V
                //W
                //X
                //Y
                //Z
                secThread.CancelAsync();
            }
0

Wozu brauchst du das? Falls der Focus sich in einer anderen Anwendung befindet geht es aus Sicherheitsgründen nicht, nehme ich mal an.

Woher ich das weiß:Berufserfahrung – Studium der Informatik + Softwareentwickler seit 25 Jahren.

verreisterNutzer  24.09.2018, 18:59

Geht auch nicht, wenn das Programm den Fokus behält.

0