 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Input
Anmeldungsdatum: 28.07.2014 Beiträge: 59
|
Verfasst am: 07.11.2014, 12:49 Titel: Programm ansprechen |
|
|
Hallo liebes Forum. Ich möchte gerne ein Programm ansprechen und die Antwort in einer Variablen speichern. Mit Pipe bekomme ich eine Antwort, jedoch nur auf dem Bildschirm. Wie kann ich nun die Ausgabe speichern? Vielen Dank!! |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4699 Wohnort: ~/
|
Verfasst am: 07.11.2014, 14:39 Titel: |
|
|
Minimales Beispiel:
aufrufendes Programm0
Code: | dim as integer f = freefile, rueckgabewert
open pipe "meinUnterprogramm.exe" for input as #f
input #f, rueckgabewert
close #f
print rueckgabewert
sleep |
aufgerufenes Programm:
edit: falsch platzierte eckige Klammer entfernt _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Zuletzt bearbeitet von nemored am 07.11.2014, 20:05, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
Input
Anmeldungsdatum: 28.07.2014 Beiträge: 59
|
Verfasst am: 07.11.2014, 16:23 Titel: |
|
|
Lieber nemored. Mein Problem ist, dass das andere Programm mit "Print" antwortet, ich aber diese Antwort gerne als Variable gespeichert hätte, um dem Programm je nach Antwort automatisch neue Befehle zu geben. Und genau das funktioniert bei mir leider nicht. Meine Frage lautet also: Wie kann ich den Bildschirm auslesen. Auch kann ich nicht einfach eine Leerzeile senden, sondern muss immer "Enter" drücken.  |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4699 Wohnort: ~/
|
Verfasst am: 07.11.2014, 20:03 Titel: |
|
|
Das PRINT in meinem zweiten Programm landet mitnichten auf dem Bildschirm, sondern in der Variable rueckgabewert des ersten Programms. Erst dieses gibt es dann auf dem Bildschirm aus.
Das, was du aber offenbar willst, ist eine bidirektionale Pipe - nach Belieben Daten in beide Richtungen schicken. So etwas ist im Sprachumfang von FreeBASIC nicht enthalten. Als Möglichkeit bietet sich die Nutzung der WinAPI an (da muss aber jemand anders weiterhelfen) oder die Verwendung einer Netzwerkbibliothek wie TSNE. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
Input
Anmeldungsdatum: 28.07.2014 Beiträge: 59
|
Verfasst am: 07.11.2014, 21:08 Titel: |
|
|
Dankeschön für deine Auskunft.  |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 07.11.2014, 21:42 Titel: |
|
|
Input hat Folgendes geschrieben: | Meine Frage lautet also: Wie kann ich den Bildschirm auslesen. |
Im QB-Zeitalter gab es dafür die SCREEN()-Funktion; diese existiert in FB prinzipiell auch immer noch:
http://www.freebasic.net/wiki/wikka.php?wakka=KeyPgScreenCons
Ob allerdings damit in einem Konsolenfenster der Output eines beendeten Kindprozesses (=mit SHELL aufgerufenes Programm) ausgelesen werden kann, müsste getestet werden. Früher in QB funktionierte dies innerhalb vom Textmodus (SCREEN 0) auf jeden Fall, weil bekanntlich der Videospeicher (B800:0000) in MS-DOS direkt die Zeichenwerte enthielt. _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
Input
Anmeldungsdatum: 28.07.2014 Beiträge: 59
|
Verfasst am: 08.11.2014, 10:08 Titel: |
|
|
Danke. Ja: SCREEN kann man auch so verwenden.  |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 08.11.2014, 10:45 Titel: |
|
|
Hallo Input!
nemored hat Folgendes geschrieben: | Als Möglichkeit bietet sich die Nutzung der WinAPI an (da muss aber jemand anders weiterhelfen) |
Ihr sucht jemand anders? Hier bin ich!
Die Erzeugung einer bidirektionalen Pipe "von Hand" ist "etwas" komplizierter, dafür aber enorm vielseitig. Auf die Gefahr hin, bei dir eine herunterklappende Kinnlade und/oder einen unwillkürlichen Schluckreflex zu verursachen, habe ich mal ein kleines Demoprogramm geschrieben.
pipe_parent.bas:
Code: | #Include Once "windows.bi"
Dim As SECURITY_ATTRIBUTES sa
Dim As STARTUPINFO si
Dim As PROCESS_INFORMATION pi
Dim As HANDLE hReadChildPipe, hWritePipe, hReadPipe, hWriteChildPipe
Dim As Integer iNumberOfBytes, iBytesAvail
Dim As String message, sBuf
'werte für sicherheitsattribute setzen
sa.nLength = SizeOf(SECURITY_ATTRIBUTES)
sa.lpSecurityDescriptor = NULL
sa.bInheritHandle = TRUE
'pipes erzeugen
CreatePipe(@hReadChildPipe,@hWritePipe,@sa,0) 'hinleitung
CreatePipe(@hReadPipe,@hWriteChildPipe,@sa,0) 'rückleitung
'startwerte für den kindprozess setzen
GetStartupInfo(@si) 'aktuelle werte holen
si.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
si.wShowWindow = SW_HIDE 'kindprozess im hintergrund (= ohne fenster) starten
si.hStdOutput = hWriteChildPipe 'standardoutput auf pipe umleiten
si.hStdError = hWriteChildPipe 'standarderror auf pipe umleiten
si.hStdInput = hReadChildPipe 'standardeingabe auf pipe umleiten
If CreateProcess(0,ExePath + "\pipe_child.exe",0,0,TRUE,0,0,0,@si,@pi) Then 'kindprozess starten
Print "Kindprozess erfolgreich gestartet"
Else
Print "Konnte Kindprozess nicht starten"
Print
Print "Weiter mit beliebiger Taste...
Sleep
End
EndIf
CloseHandle(hWriteChildPipe) 'ressourcen freigeben
CloseHandle(hReadChildPipe)
Do
Input "Nachricht ";message
message += Chr(10) 'kennzeichen für zeilenende anhängen
WriteFile(hWritePipe,StrPtr(message),Len(message),@iNumberOfBytes,0) 'nachricht zum kindprozess schicken
Sleep 1 'warten, bis operation ausgeführt wurde
Do 'auf nachricht vom kindprozess warten
PeekNamedPipe(hReadPipe,0,0,0,@iBytesAvail,0)
Sleep 1
Loop Until iBytesAvail
sBuf = String(iBytesAvail,Chr(0)) 'pufferstring erzeugen
ReadFile(hReadPipe,StrPtr(sBuf),iBytesAvail,@iNumberOfBytes,0) 'nachricht aus pipe holen
sBuf = Left(sBuf,Len(sBuf) - 2) 'zeilenumbruch entfernen
If sBuf = "ECHO quit" Then 'programm beenden
Exit Do
Else
Print sBuf 'nachricht vom kindprozess ausgeben
EndIf
Loop
TerminateProcess(pi.hProcess, 0) 'kindprozess beenden
CloseHandle(hWritePipe) 'pipes schliessen
CloseHandle(hReadPipe) |
pipe_child.bas:
Code: | Dim As String g
Do
Input g
Print "ECHO ";g
Loop |
Bevor du pipe_parent startest, mußt du pipe_child kompilieren und im selben Verzeichnis ablegen.
Das Programmpärchen macht nichts weiter, als alles, was du eingibst, mit einem vorangestellten "ECHO " zurückzuschicken, aber ich hoffe, die Funktionsweise wird dabei deutlich.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
|
Nach oben |
|
 |
Input
Anmeldungsdatum: 28.07.2014 Beiträge: 59
|
Verfasst am: 08.11.2014, 11:56 Titel: |
|
|
Also mein Spiel sieht erstmal so aus:
pipe.bas
Code: |
dim as integer i,j
dim as string text
'Sendet Passwort
for i=990 to 1100
open pipe "program.exe" for output as #1
print #1,i
close
open "program.exe" for input as #1
text=input(eof(1),1)
if text<>"" then print text
close
'Sucht Antwort
open "program.txt" for output as #1
for j=1 to 20
text=chr(screen(1,j,0))
print #1,text;
next
close
'Speichert Passwort
open "program.txt" for input as #1
input #1,text
if instr(text,"Test bestanden") then
close
open "program.txt" for output as #1
print #1,i,text
close
shell "START Notepad.exe program.txt"
sleep
end
end if
close
next
|
program.bas
Code: |
dim as string pw
input "Passwort:",pw
if pw="1000" then print "Test bestanden"
|
|
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 09.11.2014, 01:31 Titel: |
|
|
@volta:
Habe ich dein Beispiel richtig verstanden: Wenn ich bei CreateFileMapping als hFile -1 angebe, wird kein File im Sinne von "Datei auf einem Datenträger" geöffnet, sondern ein dwMaximumSize großer Bereich im Arbeitsspeicher reserviert, auf den dann jeder Prozess, der den Pointer kennt, zugreifen kann?
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 09.11.2014, 03:46 Titel: |
|
|
Das ist (fast) korrekt, wobei diese magische -1 in der WinAPI den Bezeichner INVALID_HANDLE_VALUE hat, den man auch statt der eigentlichen Zahl verwenden sollte.
Und ja, darauf kann dann im Prinzip jeder Prozess zugreifen, wobei CreateFileMapping keinen Pointer zurückgibt, sondern ein Handle. Mit dem Handle können andere Prozesse erst mal nix anfangen, allerdings kann man Handles duplizieren und andere Prozesse weiterreichen, was allerdings ein wenig Komplex ist.
Einfacher ist es da, ein benanntes Mapping-Objekt zu verwenden, was auch das FBPortal-Beispiel tut. Man sollte es aber tunlichst vermeiden, einen zu generischen Namen für dieses Filemapping zu wählen. Ein guter Name wäre z.B. "Local\MeinTollesProgramm-", gefolgt von der Prozess-ID oder einer zufälligen Zahl. Das Prefix "Local\" sollte dabei verwendet werden, um das Mapping explizit im Kontext der aktuellen Sitzung zu erzeugen.
Der Name, den du angibst, muss dem anderen Programm bekannt sein (kann z.B. per Kommandozeilenparameter übergeben werden), aber er kann halt grundsätzlich auch von jedem anderen Programm angesprochen werden. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 09.11.2014, 08:44 Titel: |
|
|
Stimmt, den Pointer liefert MapViewOfFile, und der ist -ich habe es inzwischen ausprobiert- in beiden Programmen gleich. Ich kann sogar mit Code: | Dim As nach Ptr np
...
np = pmem
...
np->n = "Gesendet von "+Titel+" es ist " + t +" Uhr." | direkt darauf zugreifen, ohne CopyMemory, sozusagen als systemweite Variable (obwohl sich das wegen der Datenkonsistenz wahrscheinlich nicht empfiehlt).
Klasse, sowas suche ich schon seit Jahren! Vielen Dank an euch beide.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 09.11.2014, 17:57 Titel: |
|
|
grindstone hat Folgendes geschrieben: | direkt darauf zugreifen, ohne CopyMemory, sozusagen als systemweite Variable (obwohl sich das wegen der Datenkonsistenz wahrscheinlich nicht empfiehlt). |
Ähm, genau das ist der Sinn hinter Shared Memory.
Man sollte aber den Zugriff bzw die Kommunikation natürlich passend synchronisieren, was nicht immer trivial ist. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 10.11.2014, 00:25 Titel: |
|
|
Jojo hat Folgendes geschrieben: | Man sollte aber den Zugriff bzw die Kommunikation natürlich passend synchronisieren, was nicht immer trivial ist. |
Das ist ja nicht anders als beim synchronisieren von Threads. Die Mutexe der WinAPI sind zwar etwas aufwendiger in der Handhabung als die von FB, aber die Anwendung ist eigentlich ganz einfach, wenn man das Prinzip einmal verstanden hat.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 10.11.2014, 13:13 Titel: |
|
|
Klar, wenn du schon mit Threads Erfahrung hast, ist es einfacher, aber ich würde mal behaupten, dass korrekte Synchronisation von Threads etwas ist, was hier viele Leuten noch nicht verstehen.  _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 11.11.2014, 03:56 Titel: |
|
|
Dabei ist es doch eigentlich ganz einfach. Es ist wie bei einer öffentlichen Toilette: Wenn sie besetzt ist, muß ich vor der Tür warten, bis mein Vorgänger fertig ist und herauskommt. Und der Mutex ist das Türschloß mit dem "BESETZT"-Schriftzug.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 11.11.2014, 08:34 Titel: |
|
|
Das ist das trivialste Szenario. Aber sobald ein paar Philosophen zusammenkommen, wird's schon komplexer...  _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 11.11.2014, 12:39 Titel: |
|
|
Ich versuche gerade, mir bildlich vorzustellen, wie jemand mit 2 Gabeln Spaghetti isst...
An dem Beispiel sieht man, daß zuviel Gleichberechtigung auch nicht gut ist. Man sollte entweder einen Rocker (der einem der Philosophen die Gabel wegnimmt) oder einen Asketen (der die Gabel wieder weglegt, um noch etwas zu fasten) mit an den Tisch setzen.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 11.11.2014, 16:03 Titel: |
|
|
Jetzt implementier mal nen Rocker oder Askete in deinem Programm... Asket geht relativ einfach, zumindest bei der WinAPI, da kann man ein Timeout setzen, und wenn man bis dahin die Ressource (Lock) nicht bekommen hat, muss man sich halt was anderes einfallen lassen. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|