VisualBasic Sendmessage und CMD

Smagjus

Rear Admiral
Registriert
Feb. 2011
Beiträge
6.142
Halllo,

ich habe ein recht einfaches Problem. Ich möchte in VB.net einen Befehl in ein bereits bestehendes CMD Fenster übermitteln. Meine erste Idee war Sendmessage. Hier ein Tutorial dazu: http://www.elitepvpers.com/forum/coding-tutorials/1184074-vb-net-sendmessage-tutorial.html

PHP:
Imports System.Runtime.InteropServices

Public Class Form1
    Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _
      (ByVal handle As IntPtr, ByVal uMsg As Integer, _
       ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr

    Const WM_SETTEXT As Integer = &HC

    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowTitle As String) As IntPtr
    End Function

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim windows As IntPtr = FindWindow(vbNullString, "Administrator: Eingabeaufforderung")
        SendMessage(windows, WM_SETTEXT, 0, TextBox1.Text)
    End Sub
End Class
Nun wird die Nachricht zwar an das Fenster versendet, allerdings verändertsich nur der Titel des Fensters in die gegebene Nachricht. Was ich will, ist aber die Nachricht an die Eingabeaufforderung zu übermitteln, als hätte ich als Nutzer einen Befehl in das Fenster einzugeben.

Spy++ gibt mir im übrigen nur das Fenster der Eingabeaufforderung an, also keine untergeordneten Steuerelemente.

Kennt da jemand eine bessere Möglichkeit? Ich wäre für alles offen (auch für C# Lösungen).


EDIT - Notlösung:
Ich habe die Methode Button1_Click abgeändert. Der Befehl, den ich nutze heißt "stop".
PHP:
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim windows As IntPtr = FindWindow(vbNullString, "Administrator: C:\Windows\system32\cmd.exe")
        SendMessage(windows, WM_CHAR, Asc("S"c), 0)
        SendMessage(windows, WM_CHAR, Asc("t"c), 0)
        SendMessage(windows, WM_CHAR, Asc("o"c), 0)
        SendMessage(windows, WM_CHAR, Asc("p"c), 0)
        SendMessage(windows, WM_CHAR, Asc(CChar(vbCr)), 0)
    End Sub
Der Code ist so dirty, da kippen selbst die Fliegen um. Ich wäre immernoch dankbar für die "richtig Lösung" ;)
 
Zuletzt bearbeitet:
Warum muss es ein bestehendes Fenster sein?
Außerdem ist dein fest gecodedes Fenster schlecht, weil der Titel sich ja ändern kann...

Habs jetzt nicht probiert, aber bestimmt lässt sich der "Stop" befehl auch in einer Zeile und nicht Zeichen für Zeichen ausführen?
 
Es handelt sich um eine Server-Client Anwendung, die wiederum auf einen Minecraftserver zugreift. Das Fenster des MCServers ist immer offen und darf nur per Stop-Befehl geschlossen werden. Deswegen die erste Einschränkung.

Die zweite Einschränkung ist das Problem mit der Eingabe Char für Char. Bisher habe ich keine Alternative finden können.

Der Titel des Fensters wird noch angepasst. Da der Server permanent läuft und immer mit der gleich .bat-Datei gestartet wird, kann sich der Titel nicht ändern. Trotzdem danke für den Hinweis.
 
Ok, wenn du es über SendMessage machen willst (mir fällt auch grad keine andere Lösung ein), dann kannst du immer noch das Senden verschönern:

Code:
Private Sub SendMessageToWindow(ByVal window As IntPtr, ByVal message as String)

[INDENT]If window = 0 Then Exit Sub

For Each character In message
[INDENT]SendMessage(window, &H102, AscW(character), 0)[/INDENT]
Next

SendMessage(window, &H102, AscW(vbChr), 0)[/INDENT]

End Sub

Und in deiner Button-Click Methode rufst du das nur noch auf, mit den passenden Parametern (also dem Window-Handle und in deinem Fall "STOP").
 
Recht hast du. Aber das ist ja nur eine kleine Schönheitsop.

Was ich persönlich merkwürdig finde, ist, dass es so schwierig ist, dazu im Netz Informationen zu finden. Schade eigentlich.
 
Vielleicht kann man ja auch direkt mit dem Minecraft-Prozess kommunizieren? Keine Ahnung, aber vielleicht lässt sich da noch was recherchieren...
 
Das hatte ich schonmal versucht. Damals hatte ich eine Verbindung zum Remote Port des Servers aufgebaut. Allerdings hat der Server alles ignoriert, was ich ihm geschickt hab, weil ich nicht wusste, welches Protokoll er haben will ;)

Von den Minecraft Freaks konnte mir auch keiner erklären, wie das funktionieren sollte. Externe Tools will ich nicht verwenden, weil mein Tool bereits jetzt mehr kann, als andere.
 
Wenn du das Fenster bereits hast, damit meine ich den zugehörigen WindowHandle, dann kannst du auch per SendInput Sequezen an das Fenster schicken.
Auf Codeplex gibt es auch einen .NET Wrapper dafür.
 
Hab gerade nicht viel Zeit, ich werde mir aber eure Lösungen noch ansehen. Vielen Dank schonmal :)
 
Zurück
Oben