String an Konsolen-Anwendung übergeben

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Justy
Beiträge: 131
Registriert: 10.09.2004 13:31
Wohnort: Feldbach / Steiermark / Österreich
Kontaktdaten:

String an Konsolen-Anwendung übergeben

Beitrag von Justy »

Hallo!

Also, gibt es irgendeine Möglichkeit (vorallem welche :mrgreen: ) einen String an ein Programm zu übergeben, das im Konsolen-Modus läuft?

Im konkreten Fall ginge es um eine GUI für die VirtualMachine QEMU.

Achtung! Ich will NICHTS an eine Windows-Eingabeaufforderung übergeben, sondern an eine eigenständige Konsole im Stil von:

Code: Alles auswählen

OpenConsole()
PrintN("Willkommen in der Konsole")
Print(">> ")
befehl$=Input()
Ich hoffe ihr könnt helfen!
Danke im voraus!
Justy
Am Anfang erschuf der Mensch Gott.
Friedrich Nietzsche
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

Der Code steht zwar auch im Archiv, dort ist er aber leicht fehlerhaft so das er nicht immer funktioniert. Hier also die überarbeite Version.

Code: Alles auswählen

#D_ReadBufferSize = 1024

Structure D_ProgramInfo 
  StartUpInfo.STARTUPINFO 
  ProcessInfo.PROCESS_INFORMATION 
  SECURITYATTRIBUTES.SECURITY_ATTRIBUTES 
  hOutputPipeRead.l 
  hOutputPipeWrite.l 
  hInputPipeRead.l 
  hInputPipeWrite.l 
  hReadThread.l 
  ReadThreadStat.l 
  ReadBuffer.l 
  ReadDataLen.l 
EndStructure 

Procedure D_ReadConsoleOutputThread(*ProgramInfo.D_ProgramInfo) 
  *ProgramInfo\ReadBuffer = AllocateMemory(#D_ReadBufferSize) 
  *ProgramInfo\ReadThreadStat = 1 
  Repeat 
    If *ProgramInfo\ReadThreadStat = 1 
      If ReadFile_(*ProgramInfo\hOutputPipeRead,*ProgramInfo\ReadBuffer,#D_ReadBufferSize,@*ProgramInfo\ReadDataLen,0) 
        *ProgramInfo\ReadThreadStat = 2 
      EndIf 
    EndIf 
    Delay(1) 
  Until *ProgramInfo\ReadThreadStat = 0 
  FreeMemory(*ProgramInfo\ReadBuffer) 
  *ProgramInfo\hReadThread = #Null 
EndProcedure 

Procedure D_RunProgram(EXEFileName.s,Parameter.s,*ProgramInfo.D_ProgramInfo) 
  Protected result 
  result = #False 
  *ProgramInfo\SECURITYATTRIBUTES\nLength = SizeOf(SECURITY_ATTRIBUTES) 
  *ProgramInfo\SECURITYATTRIBUTES\bInheritHandle = 1 
  *ProgramInfo\SECURITYATTRIBUTES\lpSecurityDescriptor = 0 
  
  If CreatePipe_(@*ProgramInfo\hOutputPipeRead, @*ProgramInfo\hOutputPipeWrite, @*ProgramInfo\SECURITYATTRIBUTES, 0) And CreatePipe_(@*ProgramInfo\hInputPipeRead, @*ProgramInfo\hInputPipeWrite, @*ProgramInfo\SECURITYATTRIBUTES, 0) 
    *ProgramInfo\StartUpInfo\cb = SizeOf(STARTUPINFO) 
    *ProgramInfo\StartUpInfo\dwFlags = #STARTF_USESTDHANDLES | #STARTF_USESHOWWINDOW 
    *ProgramInfo\StartUpInfo\hStdOutput = *ProgramInfo\hOutputPipeWrite 
    *ProgramInfo\StartUpInfo\hStdError = *ProgramInfo\hOutputPipeWrite 
    *ProgramInfo\StartUpInfo\hStdInput = *ProgramInfo\hInputPipeRead 
    If CreateProcess_(#Null,Chr(34)+EXEFileName+Chr(34)+" "+Parameter,@*ProgramInfo\SECURITYATTRIBUTES,@*ProgramInfo\SECURITYATTRIBUTES,1,#NORMAL_PRIORITY_CLASS,#Null,#Null,@*ProgramInfo\StartUpInfo,@*ProgramInfo\ProcessInfo) 
      *ProgramInfo\hReadThread = CreateThread(@D_ReadConsoleOutputThread(),*ProgramInfo) 
      If *ProgramInfo\hReadThread 
        Delay(10) 
        result = #True 
      EndIf 
    EndIf 
    CloseHandle_(*ProgramInfo\hOutputPipeWrite) 
    CloseHandle_(*ProgramInfo\hInputPipeRead) 
  EndIf 
  ProcedureReturn result 
EndProcedure 

Procedure D_CloseProgram(*ProgramInfo.D_ProgramInfo) 
  *ProgramInfo\ReadThreadStat = 0 
  CloseHandle_(*ProgramInfo\ProcessInfo\hThread) 
  CloseHandle_(*ProgramInfo\hOutputPipeRead) 
  CloseHandle_(*ProgramInfo\hInputPipeWrite) 
  TerminateProcess_(*ProgramInfo\ProcessInfo\hProcess,0) 
  CloseHandle_(*ProgramInfo\ProcessInfo\hProcess) 
  If *ProgramInfo\hReadThread 
    KillThread(*ProgramInfo\hReadThread) 
  EndIf 
EndProcedure 

Procedure D_GetOutput(*ProgramInfo.D_ProgramInfo,Buffer) 
  Delay(5) 
  If *ProgramInfo\ReadThreadStat = 2 
    OemToCharBuff_(*ProgramInfo\ReadBuffer,Buffer,*ProgramInfo\ReadDataLen) 
    *ProgramInfo\ReadThreadStat = 1 
    ProcedureReturn *ProgramInfo\ReadDataLen 
  EndIf 
  ProcedureReturn #False 
EndProcedure 

Procedure D_SendInputString(*ProgramInfo.D_ProgramInfo,string.s) 
  Protected tmp.l 
  CharToOemBuff_(string,string,Len(string)) 
  If WriteFile_(*ProgramInfo\hInputPipeWrite,string,Len(string),@tmp,0) 
    ProcedureReturn tmp 
  EndIf 
  ProcedureReturn #False 
EndProcedure 

Procedure D_SendInput(*ProgramInfo.D_ProgramInfo,Buffer.l,Bufferlen.l) 
  Protected tmp.l 
  If WriteFile_(*ProgramInfo\hInputPipeWrite,Buffer,Bufferlen,@tmp,0) 
    ProcedureReturn tmp 
  EndIf 
  ProcedureReturn #False 
EndProcedure 


#Gadget_String = 0 

CreateGadgetList(OpenWindow(0,0,0,400,200,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Console-Zeugs")) 
StringGadget(#Gadget_String,0,0,400,200,"",#PB_String_MultiLine|#PB_String_ReadOnly) 


Mem = AllocateMemory(#D_ReadBufferSize) 

If D_RunProgram("cmd","",@ProgramInfo.D_ProgramInfo) ; In ProgramInfo werden die Daten gespeichert 
  
  Repeat 
    len = D_GetOutput(@ProgramInfo,Mem) 
    If len 
      SetGadgetText(#Gadget_String,GetGadgetText(#Gadget_String)+PeekS(Mem,len)) 
    EndIf 
  Until len = 0 
  
  tmpstring.s = "net view"+Chr(13)+Chr(10) ; !WICHTIG! CHR(10) muss vorkommen, sonst wird der Befehl nicht angenommen 
  D_SendInputString(@ProgramInfo,tmpstring) 
  
  Repeat 
    len = D_GetOutput(@ProgramInfo,Mem) 
    If len 
      SetGadgetText(#Gadget_String,GetGadgetText(#Gadget_String)+PeekS(Mem,len)) 
      Received + len 
    EndIf
  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
  D_CloseProgram(@ProgramInfo) 
Else
  MessageRequester("","Konnte Programm nicht ausführen!",16)
EndIf

FreeMemory(Mem)
Sollte mit jeder Konsole funktionieren.
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
Justy
Beiträge: 131
Registriert: 10.09.2004 13:31
Wohnort: Feldbach / Steiermark / Österreich
Kontaktdaten:

Beitrag von Justy »

Danke vielmals, mit cmd funktioniert es problemlos!

Leider aber nicht mit qemu, es wird einfach nichts übergeben :cry:
weder wenn ich es direkt starte, noch wenn es aus cmd gestartet wird

Ein grund könnte sein, dass zwei fenster geöffnet werden, ein grafik-bildschirm und eine konsole, aber das kann ich mir auch irgendwie nicht vorstellen wenn ich mir den code so ansehe... :?
Am Anfang erschuf der Mensch Gott.
Friedrich Nietzsche
mipooh
Beiträge: 226
Registriert: 12.12.2004 04:49
Kontaktdaten:

Beitrag von mipooh »

Quemu ist doch eine virtuelle Umgebung, Die dürfte keinen Kontakt zum Host-OS erlauben, ausser das was eingebaut ist. Dein Gui muss also auf dem OS laufen das in Quemu läuft. Nach meinen paar Versuchen hier laufen zB manche Linux-Versionen nicht darin.
Gruss
Mipooh
Benutzeravatar
Justy
Beiträge: 131
Registriert: 10.09.2004 13:31
Wohnort: Feldbach / Steiermark / Österreich
Kontaktdaten:

Beitrag von Justy »

mipooh hat geschrieben:Dein Gui muss also auf dem OS laufen das in Quemu läuft.
Das ist schon klar, mein Qemu läuft unter Windows und die gui auch. Die gui soll jetzt in laufzeit auf die "Steuerungskonsole" von Qemu zugreifen um z.b. eine CD zu wechseln...

mipooh hat geschrieben: Nach meinen paar Versuchen hier laufen zB manche Linux-Versionen nicht darin.
Mipooh
Mein Mandrake Linux 9.1 geht problemlos mit QEMU

mfg. Justy
Am Anfang erschuf der Mensch Gott.
Friedrich Nietzsche
mipooh
Beiträge: 226
Registriert: 12.12.2004 04:49
Kontaktdaten:

Beitrag von mipooh »

Ich denke nicht dass das geht.
Sobald Quemu gestartet ist gibt es "von aussen" keinen Einfluss mehr, nur noch von Innen.
Ich gehe davon aus, dass zB die Umschaltung der Betriebssysteme jeweils aus dem anderen heraus arbeitet, also rein ins Quemu von Windows aus und rein zu Windows von Quemu aus. Selbst wenn dieselbe Tastenkombination vorgaukelt, es sei noch ein Computer. Es sind zwei.

Gruss
Mipooh
Benutzeravatar
Justy
Beiträge: 131
Registriert: 10.09.2004 13:31
Wohnort: Feldbach / Steiermark / Österreich
Kontaktdaten:

Beitrag von Justy »

entweder verstehe ich nicht worauf du hinauswillst oder es ist umgekehrt :|

Also:

Wenn man qemu startet, wird ein fenster geöffnet in dem die emulation angezeigt wird (also ein screen) UND noch ein konsolen-fenster für die steuerung von qemu, ähnlich OpenConsole. Achtung: diese Konsole wird im Host-System geöffnet (in dem fall windows). Darin kann man dann steuerungsbefehle eingeben, z.b. cd wechseln, emu pausieren...

und diese Konsole möchte ich mit meinem programm ansteuren. also z.b. ich klicke in MEINER gui auf eine "CD wechseln"-Button und das programm übergibt z.b. "change device...." and die steuerungkonsole von qemu.

Ich hoffe das war jetzt ausführlich genug, genauer schaff ich es nicht mehr :(

ich denke schon, dass das möglich ist, immerhin kann man ja auch virtuelle "Tastatureingaben" an andere Programme übergeben (z.b. Passwort-Recovery)

mfg. Justy
Am Anfang erschuf der Mensch Gott.
Friedrich Nietzsche
Antworten