C#, Backgroundworker und SendKeys?
Guten Tag,
Ich benutze einen Backgroundworker und der soll SendKeys ausführen, das geht aber nicht. Ist das mit einem Backgroundworker nicht möglich?
Wenn ich zum Test eine MessageBox rein mache, wird diese auch angezeigt. Der Backgroundworker ist also aktiviert.
Aber wieso geht SendKeys.Send("..."); nicht?
3 Antworten
Ein Beispiel, vielleicht hilft dir das weiter:
- Eine einfache Windows Forms Applikation anlegen.
- Textbox, Button und BackgroundWorker auf die Form ziehen.
- Button mit Klick-Event-Handler ausstatten.
- 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));
Gibt es eine Möglichkeit, einen Thread zu erstellen, der das macht und denn dann zu starten und zu stoppen? Funktioniert es damit besser?
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?
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();
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?
Speichere dir den Thread in einem Feld und verwende die Methode Abort zum Stoppen.
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.
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.
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.
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.
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.
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();
}
Greifst du in deinem Worker Thread auf das Clipboard (Zwischenablage) zu?
Wozu brauchst du das? Falls der Focus sich in einer anderen Anwendung befindet geht es aus Sicherheitsgründen nicht, nehme ich mal an.
Das mit der Textbox habe ich schon mal probiert, hat nicht funktioniert. Könnte das vielleicht am Framework liegen?