Entwickler-Ecke

Sonstiges (.NET) - Andere Programme bedienen


nabralanca - Di 24.02.09 16:09
Titel: Andere Programme bedienen
Hallo, ich meld mich mal wieder.
(weiß aber nicht ob dass hie im thema richtig ist^^)

ich habe vor, ein programm zu schreiben, was andere programme bedient, heißt dass das mein programm erkennt, was das zu bedienende von sich gibt, und textfelder ausfüllen, und masuklicks simulieren kann.

Zuerst würde ich mich gerne über die Maussteuerung "hermachen":
wie man den Cursor auf eine position setzt weiß ich, nur wie sagt man ihm dass er auch klicken soll???

mfg nab


Th69 - Di 24.02.09 18:57

Meinst du Programme wie AutoIt ([url]http://www.autoitscript.com[/url])?

Einen Mausklick kannst du mittels

Quelltext
1:
SendMessage(WM_CLICK, ...)                    

simulieren.


nabralanca - Mi 25.02.09 09:30

So, irgendiwe funktioniert das ganze nicht, fehlt vieleicht irgend ein verweis oder so???
oder geht des nur mit der profesional edition, ich hab express


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
private void button2_Click(object sender, EventArgs e)
        {
            Cursor.Position = new Point(760240);
            SendMessage(WM_CLICK, ...)
        }}}


JüTho - Mi 25.02.09 10:49

user profile iconnabralanca hat folgendes geschrieben Zum zitierten Posting springen:
So, irgendiwe funktioniert das ganze nicht,

Geht es vielleicht genauer? "Irgendwie" ist normalerweise keine genaue Problembeschreibung. (In Deinem Fall kann ich mir freilich vorstellen, dass Du einfach keine Reaktion erkennen kannst.)

user profile iconnabralanca hat folgendes geschrieben Zum zitierten Posting springen:
fehlt vieleicht irgend ein verweis oder so???

Nein: Wenn das der Fall ist/wäre, sagt es schon der Compiler.

user profile iconnabralanca hat folgendes geschrieben Zum zitierten Posting springen:
oder geht des nur mit der profesional edition, ich hab express

Nein, das kann nicht der Grund sein. Die Express-Version enthält nur Einschränkungen bei der Entwicklung von Programmen; aber die Ausführung benutzt ein einheitliches NET.

Versuche einmal, Cursor.Clip einzubinden. Vielleicht ist das irgendwo auf das Formular eingeschränkt worden.

Aber ich sehe gerade: Es gibt die Cursor-Klasse auch im Namespace System.Messaging. Vielleicht musst Du exakt diesen Cursor benutzen.

Gruß Jürgen


nabralanca - Mi 25.02.09 11:07

user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:

Aber ich sehe gerade: Es gibt die Cursor-Klasse auch im Namespace System.Messaging. Vielleicht musst Du exakt diesen Cursor benutzen.


Hab ich mal hinzugefügt, es kommt folgender komplier fehler(öfter)
Fehler 1 Auf den Member "System.Windows.Forms.Cursor.Position.get" kann nicht mit einem Instanzenverweis zugegriffen werden. Qualifizieren Sie ihn stattdessen mit einem Typnamen. C:\Users\Benjamin_2\Documents\Visual Studio 2008\Projects\position\position\Form1.cs 27 46 position

bei folgendem code:


C#-Quelltext
1:
2:
3:
4:
textBox1.Text = Convert.ToString(Cursor.Position.X);
            textBox2.Text = Convert.ToString(Cursor.Position.Y);

Cursor.Position = new Point(760240);

Cusor.position ist unteringeld


JüTho - Mi 25.02.09 11:16

Schau Dir doch die Fehlermeldung an:
Zitat:
Qualifizieren Sie ihn stattdessen mit einem Typnamen.

Soll der Compiler denn bei Klassen, die es in zwei using-Namespaces gibt, würfeln, welche er nehmen soll? Nein, das musst Du erledigen:

C#-Quelltext
1:
2:
3:
4:
//  entweder:
System.Windows.Forms.Cursor.Position = new Point(760240);
//  oder:
System.Messaging.Cursor.Position = new Point(760240);

Aber dann gibt es ggf. den nächsten Compilerfehler, der zeigt, dass mein Hinweis auf System.Messaging nicht passte.

Aber das waren ja sowieso nur Vermutungen; ausprobieren und umsetzen musst Du selbst. Jürgen


nabralanca - Mi 25.02.09 11:18

thx

das untere geht nicht, es geht nur die obere Variante, werd jetzt ein bischen ausprobieren


Kha - Mi 25.02.09 11:19

user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Aber ich sehe gerade: Es gibt die Cursor-Klasse auch im Namespace System.Messaging. Vielleicht musst Du exakt diesen Cursor benutzen.
Bei System.Messaging geht es um Networking ;) ...

@user profile iconnabralanca: Dein allererster Cursor-Code war schon richtig so, user profile iconTh69s Code ist allerdings nur ein Beispiel-Code, der vielleicht in Delphi aber nicht in C# direkt übernommen werden kann. Da müsstest du etwas Eigeninitiative zeigen und dich einmal in die Themen Windows-API/Window Messages und P/Invoke einlesen. Trivial ist das Thema jedenfalls nicht.


nabralanca - Mi 25.02.09 11:27

win api,

davon wurde schon viel geschreiben, hab ich auch schon einiges drüber gelesen, muss man dass extra downloaden oder so???

und kann ich das messaging sozusagen vergesen


Th69 - Mi 25.02.09 11:39

Ich habe mir eigentlich ein bißchen mehr Eigeninitiative vom Threadersteller vorgestellt!

Wenn du aber noch keine Ahnung von WinAPI etc. hast, dann such dir lieber ein einfacheres Projekt (zwei Zahlen addieren oder so -).

Hier aber mal der Link, wie man SendMessage in C# einbindet: http://www.pinvoke.net/default.aspx/user32/SendMessage.html

Und den Wert für die Konstante 'WM_CLICK' mußt du dir auch noch aus dem großen WWW (oder aber mittels des Win-SDKs) raussuchen...

Edit: Offiziell heißt die Konstante 'WM_LBUTTONDOWN'


JüTho - Mi 25.02.09 11:44

user profile iconnabralanca hat folgendes geschrieben Zum zitierten Posting springen:
win api,
davon wurde schon viel geschreiben, hab ich auch schon einiges drüber gelesen, muss man dass extra downloaden oder so???

Dazu kann ich nur wiederholen:
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Da müsstest du etwas Eigeninitiative zeigen und dich einmal in die Themen Windows-API/Window Messages und P/Invoke einlesen.

Ich bin einfach mal in den Index des OpenBook Visual C# [http://openbook.galileocomputing.de/visual_csharp/visual_csharp_20_002.htm#ix1ff1154285cb7f41fa74877768cbc805] gegangen und habe den Hinweis auf 20.2 API-Aufrufe mit PInvoke [http://openbook.galileocomputing.de/visual_csharp/visual_csharp_20_002.htm#ix1ff1154285cb7f41fa74877768cbc805] gefunden. Soviel Eigeninitiative hättest Du wirklich selbst aufbringen können.

Da ist nichts herunterzuladen; das sind Standard-Möglichkeiten des NET Framework - aber eben alles andere als trivial.

user profile iconnabralanca hat folgendes geschrieben Zum zitierten Posting springen:
und kann ich das messaging sozusagen vergesen

Wenn Du mein "vielleicht" mit System.Messaging.Cursor meinst: ganz offensichtlich und zweifelsfrei ja. Das war doch schon dadurch klar, dass es dort kein Position gibt; das hättest Du durch einen eigenen Blick in die SDK-Doku/MSDN auch selbst feststellen können. Sebastian hat "nur" noch die inhaltliche Begründung geliefert.

Jürgen


nabralanca - Mi 25.02.09 12:11

Gut danke, ich hab die lösung,


FragSalat - Sa 13.06.09 11:03

kannst ja dann vllt nochmal deine lösung posten wie du es nun machst mit in ein fremdes fenster klicken


dennis666 - Do 18.06.09 13:54

Das fänd ich mal klasse.. suche momentan nämlich nach der gleichen Problemlösung und würde mir gerne einen Beispielcode ansehen, bevor ich mich sinnlos in eventuell falsche Richtungen verbeiße ; )


FragSalat - Fr 19.06.09 15:39

kannste knicken hier schreibt dir keiner den code ich warte auch schon ewig


dennis666 - Fr 19.06.09 16:25

Da man ja so ziemlich alles auch mit der Tastatur bedienen kann (naja.. jedenfalls das meiste ^^) habe ich über SendKeys.Send einen Umweg genommen.

Hier beispielsweise um das Fenster zu wechseln (also ALT + TAB):


C#-Quelltext
1:
SendKeys.Send("%({TAB)");                    

...wobei das %-Zeichen für eine gedrückte ALT-Taste steht.

Den Taskmanager kann man z.B. mit

C#-Quelltext
1:
SendKeys.Send("%^({DEL)");                    

öffnen.

Hier ein Link für die Befehlsliste:
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx

Wenn man einfache Buchstabenkombinationen senden möchte, geht das auch so:


C#-Quelltext
1:
2:
3:
4:
private void textBox1_MouseClick(object sender, MouseEventArgs e)
{
    SendKeys.Send("(Hallo Test)");
}


Damit wird nach dem Mausklick der String gesendet und erscheint im Textfeld.

Wie gesagt eine kleine Umgehung, Mausklick simulieren würde mich immer noch interessieren...

EDIT: Fehler im kopierten Scriptauszug verbessert


FragSalat - Fr 19.06.09 16:29

das ist nicht das was gesucht wird denke ich denn ich suche eine möglichkeit ne tastenkombi an nen fenster zu senden ohne das fenster aufrufen zu müssen


dennis666 - Fr 19.06.09 16:30

Im Übrigen wird, wenn man durch den Send("%({TAB)") Befehl das Fenster wechselt, trotzdem das Script weiter ausgeführt. Wenn man also z.B. den Texteditor offen hat, kann man mit dem ALT + TAB Befehl das Fenster zum Editor wechseln, einen Text "eingeben", und dann mit dem Befehl für STRG + P drucken!

Zur Ausführung muss das Programm nicht im Vordergrund sein (was ich erst gedacht hatte, dann aber positiv überrascht festgestellt hab).


dennis666 - Fr 19.06.09 16:31

user profile iconFragSalat hat folgendes geschrieben Zum zitierten Posting springen:
das ist nicht das was gesucht wird denke ich denn ich suche eine möglichkeit ne tastenkombi an nen fenster zu senden ohne das fenster aufrufen zu müssen


Hmmm.. dann weiß ich auch keinen Weg... Aber mit Mausklick müsstest du das Fenster doch auch öffnen, oder?


FragSalat - Fr 19.06.09 16:34

naja mit PostMessage kann man tasten an prozesse und fenster senden ohne das die sichtbar sein müssen damit kann man auch mausklicks senden nur hab ich nicht so genau ne ahnung wie ich hab nen beispiel in visual basic aber das funzt nicht wenn ichs in c# anwende


Kha - Fr 19.06.09 17:13

user profile iconFragSalat hat folgendes geschrieben Zum zitierten Posting springen:
ich hab nen beispiel in visual basic aber das funzt nicht wenn ichs in c# anwende
Sollte es aber theoretisch ;) . Hier [http://c-sharp-forum.de/viewtopic.php?p=551159#551159] wurden ja schon ein paar Ansätze genannt, ansonsten bräuchten wir das VB-Original und deine Übersetzung.


FragSalat - Sa 04.07.09 23:31


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
        public void SendMouseClick(Process proc, Point location)
        {
            // this private method sends mouse clicks to a given point location
            // get the process' window handle
            IntPtr hWnd = GetWindowHandle(proc);
            // store the handle and process in a HandleRef
            HandleRef hRef = new HandleRef(proc, hWnd);
            // send the MouseButtonDown message using SendMessage
            win32API.SendMessage(hRef, System.Convert.ToUInt32(win32API.WM_Cmd.WM_LBUTTONDOWN), IntPtr.Zero, (IntPtr)(((location.Y * 0X10000) + location.X)));
            // sleep a bit
            System.Threading.Thread.Sleep(50);
            // send the MouseButtonUp message using SendMessage
            win32API.SendMessage(hRef, System.Convert.ToUInt32(win32API.WM_Cmd.WM_LBUTTONUP), IntPtr.Zero, (IntPtr)(((location.Y * 0X10000) + location.X)));



damit will ich nen mausklick senden habs aber auch schon damit probiert


C#-Quelltext
1:
2:
SendMessage(HWND, WM_LBUTTONDOWN, MK_LBUTTON, (((location.Y * 0X10000) + location.X)));
SendMessage(HWND, WM_LBUTTONUP, MK_LBUTTON, (((location.Y * 0X10000) + location.X)));


was aber auch nicht geht