| 
				
					|  | 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, 11: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: 4711
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 07.11.2014, 13: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, 19:05, insgesamt einmal bearbeitet
 |  |  
		| Nach oben |  |  
		|  |  
		| Input 
 
 
 Anmeldungsdatum: 28.07.2014
 Beiträge: 59
 
 
 | 
			
				|  Verfasst am: 07.11.2014, 15: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: 4711
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 07.11.2014, 19: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, 20:08    Titel: |   |  
				| 
 |  
				| Dankeschön für deine Auskunft.  |  |  
		| Nach oben |  |  
		|  |  
		| dreael Administrator
 
  
 Anmeldungsdatum: 10.09.2004
 Beiträge: 2530
 Wohnort: Hofen SH (Schweiz)
 
 | 
			
				|  Verfasst am: 07.11.2014, 20: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, 09:08    Titel: |   |  
				| 
 |  
				| Danke.  Ja: SCREEN kann man auch so verwenden.  |  |  
		| Nach oben |  |  
		|  |  
		| grindstone 
 
 
 Anmeldungsdatum: 03.10.2010
 Beiträge: 1283
 Wohnort: Ruhrpott
 
 | 
			
				|  Verfasst am: 08.11.2014, 09: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, 10: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: 1283
 Wohnort: Ruhrpott
 
 | 
			
				|  Verfasst am: 09.11.2014, 00: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, 02: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: 1283
 Wohnort: Ruhrpott
 
 | 
			
				|  Verfasst am: 09.11.2014, 07:44    Titel: |   |  
				| 
 |  
				| Stimmt, den Pointer liefert MapViewOfFile, und der ist -ich habe es inzwischen ausprobiert- in beiden Programmen gleich. Ich kann sogar mit direkt darauf zugreifen, ohne CopyMemory, sozusagen als systemweite Variable (obwohl sich das wegen der Datenkonsistenz wahrscheinlich nicht empfiehlt). 	  | Code: |  	  | Dim As nach Ptr np ...
 np = pmem
 ...
 np->n = "Gesendet von "+Titel+" es ist " + t +" Uhr."
 | 
 
 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, 16: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: 1283
 Wohnort: Ruhrpott
 
 | 
			
				|  Verfasst am: 09.11.2014, 23: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, 12: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: 1283
 Wohnort: Ruhrpott
 
 | 
			
				|  Verfasst am: 11.11.2014, 02: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, 07: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: 1283
 Wohnort: Ruhrpott
 
 | 
			
				|  Verfasst am: 11.11.2014, 11: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, 15: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.
 
 |  |