Nachrichten an die Eingabeaufforderung senden

Hallo,

ich habe zwei unübersichtliche Konsolenprogramme, die über F- Tasten gesteuert und bei denen noch einige Daten über die Tastatur eingegeben werden müssen.
Nun möchte ich ein Windowsprogramm schreiben, das diese beiden Programme steuert. Meine Idee war, Nachrichten über „SendMessage“ zu schicken. Bei nem Windows- Programm wie NotePad geht das auch einwandfrei, aber bei der Konsole komme ich nicht an den Editorbereich. Das Einzige,was ich ändern kann, ist der Text in der Titelzeile. Der Rest scheint wohl von Windows geschützt zu sein.
Mit Spy++ bekomme ich nur die Meldung: „… Windows lässt den Zugriff auf die Nachrichtenfolge für dieses Fenster nicht zu“

Hat jemand ne Idee wie ich die Konsolenprogramme steuern kann? Müsste ja irgendwie die Tastatur simulieren.

gruss
ziba

Hallo,

ich habe zwei unübersichtliche Konsolenprogramme, die über
F-Tasten gesteuert und bei denen noch einige Daten über
die Tastatur eingegeben werden müssen.
Nun möchte ich ein Windowsprogramm schreiben, das diese beiden
Programme steuert. Meine Idee war, Nachrichten über
„SendMessage“ zu schicken. Bei nem Windows- Programm wie
NotePad geht das auch einwandfrei, aber bei der Konsole komme
ich nicht an den Editorbereich.

Das kommt darauf an, wie Dein programm
die Tastatureingabe realisiert. Wenn
es nur (im Programm) mit DOS-Standardeingabe
hantiert, kannst Du die Tastatureingabe
in eine Binärdatei schreiben:

C\\> copy con eingabe.dat
Y
Y
N
EXIT
^Z
C\>

Nicht vergessen, mit ^Z oder F6
abzuschliessen… Dann kannst Du Dein
Programm mit:

C\\>meinprog.exe starten.
Falls das Programm aber "eigenwillig" mit
der Tastatur umspringt, z.B. DOS INT21, FN=0Bh
(GET STDIN STATUS) oder DOS INT21, FN=0Ch
(FLUSH BUFFER AND READ STANDARD INPUT), oder
gar BIOS-INT verwendet, hast Du erfahrungsgemäß
kaum eine Chance.

Was für ein Programm ist es denn und wie
sieht die Eingabe aus?

Grüße

CMБ

Danke erstmal für die Antwort:

Was ich zu den alten Programmen noch rausgefunden habe ist, dass es DOS- Programme sind. Es macht einen Unterschied, ob ich
keybd_event( VK_NUMPAD1,0,KEYEVENTF_EXTENDEDKEY | 0, 0 ); an ein von mir schriebenes Konsolenprogramm sende oder an die Dos- Programme.
Die Dos- Programme reagieren nicht auf die Eingaben.

Die Idee mit der Binärdatei funktioniert zwar grundsätzlich auch mit den alten Programmen, allerdings kann ich keine Zeichen/ Bedienungen mehr nachschieben, wenn das Programm einmal läuft. (muss dynamisch bedienen können: z.B. wenn in meinem Windowsprogramm ein Button geklickt wird–> im Dos- Prgramm Funktion hinter F2 ausführen)

Wie das Einlesen in den alten Programmen funktioniert kann ich leider auch nicht genau sagen (der, der die Progs geschrieben hat ist auch nicht mehr erreichbar). Hatte nur was mit getLine, gets,… gefunden.
Die Befehle die du oben geschrieben hattest, konnte ich nicht finden.

gruss
ziba

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Noch ne Frage zu der Binärdatei, die den Eingabestrom darstellt:

…, kannst Du die Tastatureingabe
in eine Binärdatei schreiben:

C\> copy con eingabe.dat
Y
Y
N
EXIT
^Z

Wie kann ich in so ne Datei Funktionstasten oder Escape reinbringen?
Als String gehts ja nicht, der wird ja auch nur als solcher interpretiert. Wie sieht dafür die Syntax aus?

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Ziba !

Die Idee mit der Binärdatei funktioniert zwar grundsätzlich
auch mit den alten Programmen, allerdings kann ich keine
Zeichen/ Bedienungen mehr nachschieben, wenn das Programm
einmal läuft. (muss dynamisch bedienen können: z.B. wenn in
meinem Windowsprogramm ein Button geklickt wird–> im Dos-
Prgramm Funktion hinter F2 ausführen)

Dann bleibt dir nur, dass DOS-Programm von deinem Programm aus zu starten und eine Pipe auf dessen stdin zu setzen.
Das würde etwa so aussehen (Code nicht getestet):

// p\_hProcess: Hier wird das ProcessHandle auf den erzeugten Prozess zurueckgegeben
// hProcessHandleStdIn: Handle auf stdin des erzeugten Prozesses
// p\_sCommandline: Kommandozeile zum Aufruf des Prozesses (z.B.: "C:\\Windows\\notepad.exe")
// p\_pArgV: Argumente des erzeugten Prozesses
int CreatePipedProcess(int \*p\_hProcess, int \*p\_hProcessHandleStdIn, char \*p\_sCommandline, char \*\*p\_pArgV)
{
 int hProcess;
 int hStdInPipe[2];
 int hStdIn;


 // Redirect child process's stdin): 
 // Create the stdin pipe
 if (pipe(hStdInPipe, 4096, O\_BINARY | O\_NOINHERIT) == -1)
 return 1;
 // Duplicate stdin handle
 hStdIn = dup(fileno(stdin));
 // Reassign read end of pipe to stdin handle
 if(dup2(hStdInPipe[PIPE\_HANDLE\_READ], fileno(stdin)) != 0)
 return 1;
 // Close original read end of stdin pipe
 close(hStdInPipe[PIPE\_HANDLE\_READ]);
 hStdInPipe[PIPE\_HANDLE\_READ] = -1;

 // Spawn process
 if ((hProcess = spawnvp(P\_NOWAIT, p\_sCommandline, p\_pArgV)) 

Wenn du diese Funktion mit enstprechenden Parametern aufrufst kannst du über hProcessHandleStdIn deine Eingabe an stdin des aufgerufenen Prozesses schicken:


    
    if (CreatePipedProcess(&hProcess, &hProcessHandleStdIn, sCommandline, pArgV) \> 0)
     return 1;
    
    if ((fProcessIn = fdopen(hProcessHandleStdIn, "a")) != NULL)
    {
     fprintf(fProcessIn, "Erste Eingabezeile.\n");
     fprintf(fProcessIn, "Zweite Eingabezeile.\n");
     fprintf(fProcessIn, "Dritte Eingabezeile.\n");
    }





mfg
Christof

Danke für die Antwort.
Die Idee ist gut, nur bei der Umsetzung hängts noch n bisschen bei mir.
Einige Funktionen und Konstanten, die du verwendest kennt Visual C++ nicht. Kann es sein, dass der Beispielcode unter Linux läuft? Für Windowsprogrammierung habe ich Funktionen wie CreatePipe oder CreateNamedPipe statt Pipe gefunden.
Ich probier jedenfalls mal weiter.

Gruß
Ziba

Ich komme mit den Pipes nicht weiter. Hab bisher folgenden Code:

void CPicUpControlDlg::open_mouth:nCreateBinFile()
{
const int cBuffer = 255; // Buffergroesse der Pipe
HANDLE hRead = NULL; //HANDLE zum Lesen
HANDLE hWrite= NULL; // Handle zum Schreiben
//unsigned long nThreadID;

SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = true;
sa.bInheritHandle = NULL;

/****************************************************************************
********************** Erzeugen der Pipe **********************************
****************************************************************************/
BOOL fCreated = CreatePipe (&hRead, &hWrite, &sa, 0);
if( !fCreated )
MessageBox(„Fehler beim Erstellen der Pipe“);
else
MessageBox(„Pipe wurde erstellt“);

/****************************************************************************
********** Prozess starten ************************************************
****************************************************************************/
STARTUPINFO si;
ZeroMemory(&si,sizeof(STARTUPINFO));

// stdin, stdout und stderr des Kindes in STARTUPINFO eintragen
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdInput = hRead;
si.hStdOutput = hWrite;
si.hStdError = hWrite;

PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

GetStartupInfo(&si);

//Den Pfad des zu startenden DOS- Programmes aus der Textfeldvar.
//in ein char[] umwandeln
char* pszString = new char[m_sPathToPicUp.GetLength() + 1];
strcpy( pszString, m_sPathToPicUp );

CreateProcess(pszString,NULL,// Name of app to launch --> oder NULL,pszString
NULL, // Default process security attributes
NULL, // Default thread security attributes
TRUE, // inherit handles from the parent
0, // Normal priority
NULL, // Use the same environment as the parent
NULL, // Launch in the current directory
&si, // Startup Information
&pi); // Process information stored upon return

/****************************************************************************
************** In die Pipe schreiben **************************************
****************************************************************************/
//TCHAR Msg[cBuffer];
CString Msg = „Test“;
DWORD dwWritten;
BOOL fWritten = WriteFile (hWrite, // schreiben in die Pipe
Msg,
sizeof(Msg),
&dwWritten,
NULL );

Erreichen möchte ich mit dem Programm, dass mein Windowsprogramm z.B. die Konsole(cmd.exe) startet und einfach den String „Test“ hinters promt schreibt.
Weis jemand, was mir noch fehlt oder was ich falsch mache?

gruss
ziba