Benutzer mit den meisten Antworten
generelle Frage: key events an windows senden

Frage
-
Hallo,
ist es generell möglich von einem Programm aus ans hostsystem (also windows7 zb.) die Message zu senden "es wurde Taste xy auf dem keyboard gedrückt" damit diese von anderen programmen ausgewertet werden kann? Natürlich ohne das die Taste wirklich physikalisch gedrückt wurde. ;)
Grüße
ee
Antworten
-
Hallo ee,
Die Tastatureingabe hat als Ziel immer das aktuell aktive Fenster, unabhängig davon ob man SendKeys.Send() verwendet, oder die SendInput()-API Funktion. In bestimmten Szenarien kann man WM_KEYUP-, WM_CHAR- und WM_KEYDOWN-Nachrichten direkt an die jeweilige Fensterprozedur über SendMessage()-API absetzen, dann funktioniert u.U. die Weitergabe von "Tastaturanschlägen" auch ohne ein aktives Fenster, eine Garantie für die (zeitnahe) Verarbeitung der Nachrichten aber - vor allem unter Windows 7 - gibt es nicht. Und: Viele betrachten es eher als Unsitte, Tastatureingaben mit WM_KEYDOWN zu simulieren. Der klassische .NET-Weg ist also: Fremdanwendung in den Vordergrund bringen und aktivieren (FindWindow/SetForegroundWindow), dann SendKeys.Send() verwenden.
Details findest Du hier:
Tasten Simulieren: Enter funktioniert nicht unter Windows 7Gruß
Marcel- Als Antwort markiert Robert BreitenhoferModerator Montag, 5. November 2012 15:59
-
Leider crasht mein Programm beim versuch die KeyEvents an die anderen Anwendungen zu verschicken.
Hallo ee,
Zunächst zum Crash: Es ist generell hilfreich, wenn man zu einem Fehler die genauen Umstände beschreibt, sowie die Fehlermeldung im Wortlaut hier postet (StackTrace erwünscht).
Ich kann mir aber in diesem Fall ehrlich gesagt schwer vorstellen, dass SendKeys.Send() zu einem Crash führen könnte, da dieses Methode intern einfach ein Keyboard-State setzt und diesen an die SendInput()-Funktion weiterdelegiert. Nichts weltbewegendes hier, wirklich.
Welche Option Du schlussendlich wählst, hängt von dem ab, was deine Anwendung machen muss. Nachfolgend eine Klasse, die beide Wege (Windows API / SendKeys.Send) implementiert:
public class SendKeysHelper { [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam); private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; public static void ActivateWindowThenSendKeys(string windowTitle, string keys) { var windowHandle = GetWindowHandleFromTitle(windowTitle); if (windowHandle != IntPtr.Zero) { SetForegroundWindow(windowHandle); SendKeys.Send(keys); } } public static void DontActivateWindowJustSendKeys(string windowTitle, int keyCode) { var windowHandle = GetWindowHandleFromTitle(windowTitle); if (windowHandle != IntPtr.Zero) SendMessage(windowHandle, WM_KEYDOWN, keyCode, IntPtr.Zero); } private static IntPtr GetWindowHandleFromTitle(string windowTitle) { var windowHandle = FindWindow(null, windowTitle); return windowHandle; } }
Wenn man Tastaturanschläge an Anwendungen schickt, muss man sich natürlich darüber im Klaren sein, dass man nur Herr über die Senderseite ist. Was die Zielanwendung daraus macht (und ob), steht auf einem anderen Blatt.
Gruß
Marcel- Als Antwort vorgeschlagen Ionut DumaModerator Donnerstag, 1. November 2012 13:00
- Als Antwort markiert Robert BreitenhoferModerator Montag, 5. November 2012 15:58
Alle Antworten
-
Hallo ee,
Die Tastatureingabe hat als Ziel immer das aktuell aktive Fenster, unabhängig davon ob man SendKeys.Send() verwendet, oder die SendInput()-API Funktion. In bestimmten Szenarien kann man WM_KEYUP-, WM_CHAR- und WM_KEYDOWN-Nachrichten direkt an die jeweilige Fensterprozedur über SendMessage()-API absetzen, dann funktioniert u.U. die Weitergabe von "Tastaturanschlägen" auch ohne ein aktives Fenster, eine Garantie für die (zeitnahe) Verarbeitung der Nachrichten aber - vor allem unter Windows 7 - gibt es nicht. Und: Viele betrachten es eher als Unsitte, Tastatureingaben mit WM_KEYDOWN zu simulieren. Der klassische .NET-Weg ist also: Fremdanwendung in den Vordergrund bringen und aktivieren (FindWindow/SetForegroundWindow), dann SendKeys.Send() verwenden.
Details findest Du hier:
Tasten Simulieren: Enter funktioniert nicht unter Windows 7Gruß
Marcel- Als Antwort markiert Robert BreitenhoferModerator Montag, 5. November 2012 15:59
-
Riesen Dank an Dich Marcel.
- Bearbeitet externalerror Sonntag, 28. Oktober 2012 08:27
-
Der klassische .NET-Weg ist also: Fremdanwendung in den Vordergrund bringen und aktivieren (FindWindow/SetForegroundWindow), dann SendKeys.Send() verwenden.
Hallo nochmal,
Meine Lösung sieht jetzt wie folgt aus, aber leider crasht mein Programm beim versuch die KeyEvents an die anderen Anwendungen zu verschicken. Lohnt es sich es weiter mit SendKeys zu versuchen oder sollte ich es lieber mit keydb_event() weiter versuchen?
private void remote() { string processname = ""; foreach (Process p in Process.GetProcesses()) { //if (p.MainWindowHandle != null && p.MainWindowTitle.Contains("Google Chrome") == true) if (p.MainWindowHandle != null && p.MainWindowTitle.Contains("Mozilla Firefox") == true) { // Prozesss mit Name und handle anzeigen //System.Windows.MessageBox.Show(p.MainWindowTitle + " -> " + p.MainWindowHandle.ToString()); processname = p.MainWindowTitle; break; } } IntPtr mybrowser = FindWindow(null, processname); if (mybrowser.ToInt32() == 0) System.Windows.MessageBox.Show(OutputErr(1)); else { SetForegroundWindow(mybrowser); SendKeys.Send("{DOWN}"); } }
Danke und Grüße
ee
-
Leider crasht mein Programm beim versuch die KeyEvents an die anderen Anwendungen zu verschicken.
Hallo ee,
Zunächst zum Crash: Es ist generell hilfreich, wenn man zu einem Fehler die genauen Umstände beschreibt, sowie die Fehlermeldung im Wortlaut hier postet (StackTrace erwünscht).
Ich kann mir aber in diesem Fall ehrlich gesagt schwer vorstellen, dass SendKeys.Send() zu einem Crash führen könnte, da dieses Methode intern einfach ein Keyboard-State setzt und diesen an die SendInput()-Funktion weiterdelegiert. Nichts weltbewegendes hier, wirklich.
Welche Option Du schlussendlich wählst, hängt von dem ab, was deine Anwendung machen muss. Nachfolgend eine Klasse, die beide Wege (Windows API / SendKeys.Send) implementiert:
public class SendKeysHelper { [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam); private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; public static void ActivateWindowThenSendKeys(string windowTitle, string keys) { var windowHandle = GetWindowHandleFromTitle(windowTitle); if (windowHandle != IntPtr.Zero) { SetForegroundWindow(windowHandle); SendKeys.Send(keys); } } public static void DontActivateWindowJustSendKeys(string windowTitle, int keyCode) { var windowHandle = GetWindowHandleFromTitle(windowTitle); if (windowHandle != IntPtr.Zero) SendMessage(windowHandle, WM_KEYDOWN, keyCode, IntPtr.Zero); } private static IntPtr GetWindowHandleFromTitle(string windowTitle) { var windowHandle = FindWindow(null, windowTitle); return windowHandle; } }
Wenn man Tastaturanschläge an Anwendungen schickt, muss man sich natürlich darüber im Klaren sein, dass man nur Herr über die Senderseite ist. Was die Zielanwendung daraus macht (und ob), steht auf einem anderen Blatt.
Gruß
Marcel- Als Antwort vorgeschlagen Ionut DumaModerator Donnerstag, 1. November 2012 13:00
- Als Antwort markiert Robert BreitenhoferModerator Montag, 5. November 2012 15:58
-
Hallo externalerror,
Ich gehe davon aus, dass die Antworten Dir weitergeholfen haben.
Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.Grüße,
RobertRobert Breitenhofer, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.