C# Tastatur-Steuerung

Zhen

Lt. Junior Grade
Registriert
Aug. 2009
Beiträge
299
Hallo Leute,
hätte da ne kleine Frage.

Ich bin gerade dabei mir ne kleine Tastensimulation zu programmieren, aber ich hab da einen Fehler und begreife einfach nicht wieso/wo er liegt.

Ich bekomme den Fehler Code 87 ausgespuckt was für "Invalid Parameter" steht... jedoch... hab ich alles genauso gemacht wie in den ganzes Tutorials und in der MSDN beschreiben steht.

Hier ist meine Test-Funktion für die Simulation:
Code:
public uint Test() {
	INPUT abc = new INPUT();
	abc.type = InputType.KEYBDINPUT; //entspricht dem Wert "1"

	abc.ki.Scan = 0;
	abc.ki.wVk = VkCode.A; //entspricht dem Wert "0x41"
	abc.ki.dwFlags = KEYEVENTF.EXTENDEDKEY; //entspricht dem Wert "0x0001"
	abc.ki.time = 0;
	abc.ki.dwExtraInfo = GetMessageExtraInfo();

	INPUT[] test = { abc };

	return SendInput(1, test, Marshal.SizeOf(abc));
}

Hoffe Ihr könnt mir helfen :)
 
Zuletzt bearbeitet:
Hier stand Blödsinn
 
Zuletzt bearbeitet: (Hier stand Blödsinn)
Warum nicht mal auskommentieren, um zu sehen woher der Fehler kommt?
Mach erstmal ne void Methode draus und kommentiere das return statement aus, ob es dann weg ist.

Vielleicht liegts an dem Aufruf return SendInput(...)
Ergänzung ()

...jaaa und?
 
Immernoch der selbe Fehler. Hab schon alles mögliche ausprobiert.
Ich hab keine Ahnung wo der Fehler liegt.

Hab außerdem ne Methode für die Maus geschrieben (dieses Tut diente dabei als Hilfestellung - http://dotnet-snippets.de/dns/maus-kontrollieren-SID432.aspx), aber nicht mal das funktioniert.

Ich hab jetzt schon mindestens zig mal den Code vom Tut und meinen eigenen durchgecheckt... es ist alles identisch und es funzt immernoch nicht!!! Aber wo ich den Code ausm Tut direkt kopiert hatte da hats schon funktioniert!!
 
Der Fehler tritt doch scheinbar beim Compilieren auf, also musst du doch wissen, welche Zeile den Fehler verursacht? Da muss doch irgendwo kommen "Fehler in Zeile XY"...

Du sagst C#, wo läuft das Teil eigentlich? .NET oder Mono? Welcher Compiler kommt zum Einsatz? Und welche Version von C#?

Mit dem Spirit den du hier an den Tag legst kommt man als Programmierer echt nicht weit :D
 
Warum so kompliziert:

Code:
System.Windows.Forms.SendKeys.Send("Hallo");


Für Sonderzeichen gibt es diese Codes:
Code:
Taste                                 Code
RÜCKTASTE                             {BACKSPACE}, {BS} oder {BKSP}
UNTBR                                 {BREAK}
FESTSTELLTASTE                        {CAPSLOCK}
ENTF oder RÜCKSCHRITT                 {DELETE} oder {DEL}
NACH-UNTEN                            {DOWN}
ENDE                                  {END}
EINGABE                               {ENTER} oder ~
ESC                                   {ESC}
HILFE                                 {HELP}
POS1                                  {HOME}
EINFG                                 {INSERT} oder {INS}
NACH-LINKS                            {LEFT}
NUM                                   {NUMLOCK}
BILD-AB                               {PGDN}
BILD-AUF                              {PGUP}
DRUCK                                 {PRTSC}
NACH-RECHTS                           {RIGHT}
ROLLEN                                {SCROLLLOCK}
TAB                                   {TAB}
NACH-OBEN                             {UP}
F1                                    {F1}
F2                                    {F2}
F3                                    {F3}
F4                                    {F4}
F5                                    {F5}
F6                                    {F6}
F7                                    {F7}
F8                                    {F8}
F9                                    {F9}
F10                                   {F10}
F11                                   {F11}
F12                                   {F12}
F13                                   {F13}
F14                                   {F14}
F15                                   {F15}
F16                                   {F16}
ADDITIONSTASTE (Zehnertastatur)       {ADD}
SUBTRAKTIONSTASTE (Zehnertastatur)    {SUBTRACT}
MULTIPLIKATIONSTASTE (Zehnertastatur) {MULTIPLY}
DIVISIONSTASTE (Zehnertastatur)       {DIVIDE}

Für Tastenkombinationen einen oder mehrere dieser Codes voranstellen:
UMSCHALT                              +
STRG                                  ^
ALT                                   %
 
Ok also... der Fehler tritt nicht beim Kompilieren auf.
Das ist ein Systemfehler den ich mit "GetLastError()" (Funktion aus der "Kernel32.dll") ausgeben kann. Bzw. gibt es nur die Fehler nummer aus! 87. Laut MSDN ist es "INVALID PARAMETER"

Benutze Visual C# 2010 Express -> also die neuste Version. Framework ist .net 4.0 unter Windows. Kein MONO.

Die Funktion "Test()" gibt übrigens 0 zurück. Laut MSDN steht es dafür dass es von einem anderen Thread blockiert wird.

Hier nochmals der Link zum Originalbeitrag in der MSDN
http://msdn.microsoft.com/en-us/library/ms646310(v=vs.85).aspx
Ergänzung ()

Ok also langsam aber sicher komme ich der Lösung näher.
Allem anschein nach liegt der Fehler bei der structure INPUT.

wenn ich das "public KEYBDINPUT ki" auskommentiere, dann
funktionieren immerhin die Mausklicks sowie -bewegungen!
 
Zuletzt bearbeitet:
Die Input-Struktur ist das Problem. MOUSEINPUT, KEYBDINPUT & HARDWAREINPUT sind in einer Union zusammengefasst, d.h sie belegen den selben Raum im Speicher.

Die Länge der INPUT-Struktur ändert sich also je nachdem welcher Typ verwendet wird.
In C# kann man das so nachbilden:
Code:
        [StructLayout(LayoutKind.Explicit)]
        private struct INPUT {
            [FieldOffset(0)] public InputType type;
            [FieldOffset(4)] public MOUSEINPUT mi;
            [FieldOffset(4)] public KEYBDINPUT ki;
            //[FieldOffset(4)] public HARDWAREDINPUT hi;
        }

Dann noch das ändern:
Code:
return SendInput(2, test, Marshal.SizeOf(new INPUT()));
in:
Code:
return SendInput(2, test, Marshal.SizeOf(abc));
 
Vielen Dank für die Antwort. Ich habs jetzt "vorerst" einmal anders gemacht, es nämlich auf 2 Klassen aufgeteilt.

Bei der Mausklasse wird wir unter INPUT "MOUSEINPUT" verwendet und in der Tastaturklasse "KEYBDINPUT".

Die Mausklasse funktioniert auch super, aber die Keyklasse will einfach nicht.
Ich versteh irgendwie nicht ganz was ich für Werte angeben muss damit der Keyevent auch ausgeführt wird.

Ich dachte an folgendes, aber es ist allem anschein nach falsch:
Code:
public static uint ZEingabe(short z) {
	INPUT key_down = new INPUT();
	key_down.type = InputType.INPUT_KEYBOARD;

	key_down.ki.wVk = z;
	key_down.ki.Scan = 0;
	key_down.ki.dwFlags = KEYEVENTF.EXTENDEDKEY;
	key_down.ki.time = 0;
	key_down.ki.dwExtraInfo = GetMessageExtraInfo();

	INPUT key_up = key_down;
	key_up.ki.dwFlags = KEYEVENTF.KEYUP;

	INPUT[] input = { key_down, key_up };
	return SendInput(2, input, Marshal.SizeOf(key_down));
}

Als Wert für Z gebe ich z.B. "0x57" an, hab es aber auch mit einer normalen Zahl schon probiert z.B. "200". Klappt trotzdem nicht.

Kannst du mir da weiterhelfen?

Und vielen vielen Dank für die Hilfe.
Ergänzung ()

Also ich bin echt langsam am abdrehen hier Leute. Ich steig einfach nicht hinter diesen verdammten Mist!!!

Ich hab jetzt ewig lang auch bei Google gesucht, aber da findet man NICHTS SINNVOLLES!! Alles nur VB Beispiele. Hab eh schon versucht diese in C# zu übersetzen.

Eigentlich müsste alles stimmen. Es müsste im aktuellen Zustand eigentlich funktionieren die Funktion. Tut es aber nicht. So sieht sie derzeit aus:

Code:
public static uint ZEingabe(short z) {
	INPUT key_down = new INPUT();
	key_down.type = InputType.INPUT_KEYBOARD;

	key_down.ki.wVk = z;
	//key_down.ki.Scan = 0;
	key_down.ki.dwFlags = 0;
	key_down.ki.time = 0;
	key_down.ki.dwExtraInfo = GetMessageExtraInfo();

	INPUT key_up = key_down;
	key_up.ki.dwFlags = KEYEVENTF.KEYUP;

	INPUT[] input = { key_down, key_up };
	return SendInput(2, input, Marshal.SizeOf(key_down));
}

Dabei ist es völlig egal ob ich das Scan auskommentiere oder nicht. Es funzt nicht!!!
Für die variable z übergebe ich einmal den Wert "65" und ein anderes mal den Wert "0x57".

Beides funktioniert nicht. Keine Ahnung wieso, hab schon alles ausprobiert, alles zig mal durchgeguckt. ES müsste eigentlich laufen.
 
Zhen schrieb:
Dabei ist es völlig egal ob ich das Scan auskommentiere oder nicht. Es funzt nicht!!!
Für die variable z übergebe ich einmal den Wert "65" und ein anderes mal den Wert "0x57".

Beides funktioniert nicht. Keine Ahnung wieso, hab schon alles ausprobiert, alles zig mal durchgeguckt. ES müsste eigentlich laufen.

Code:
abc.ki.Scan = (short)'a';
abc.ki.wVk = 0;
abc.ki.dwFlags = KEYEVENTF.UNICODE;

Edit: Zum direkten testen in Visual C# "Starten OHNE Debugging" (Ctrl+F5)
 
Ok ich danke allen für die Hilfe (besonders lynxx).
Hab es nun endlich geschafft es zum laufen zu bringen =)

Also ich weiß nun woran das lag und vor allem habe ich nun mit etwas Hilfe sogar verstanden wieso =D

1. abc.ki.Scan = 0; abc.ki.wVk = 0x57; abc.ki.dwFlags = 0x0000; funktioniert.
2. wieso es NICHT funktioniert hat lag allein an meiner Structure!

Ich habe nämlich 2 Klassen gehabt. Einmal für Maus und einmal für Keyboard.

Maus INPUT structure:
Code:
private struct INPUT {
	public InputType type;
	public MOUSEINPUT mi;
}

Keyboard INPUT structure:
Code:
private struct INPUT {
	public InputType type;
	public KEYBDINPUT ki;
}

diese 2 inputs waren in 2 verschiedenen Klassen. Der Mausinput wurde ausgeführt Keybdinput allerdings nicht.

Nachdem ich es umgeändert hab in die FieldOffset lief es einwandfrei:
Code:
private struct INPUT {
	[FieldOffset(0)]
	public InputType type;
	[FieldOffset(4)]
	public MOUSEINPUT mi;
	[FieldOffset(4)]
	public KEYBDINPUT ki;
	//[FieldOffset(4)] public HARDWAREDINPUT hi;
}

Dieses Thema kann dann somit geschlossen werden. Ich danke allen nochmals für die Hilfe =)
 
Zurück
Oben