Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

WriteFile and the ENTER keystroke

richpauir
Beginner
1,624 Views
I am using QuickWin to display the output from a console program. I have used CreatePipe to set up an input and an output pipe for the console's hStdInput and hStdOutput. The two pipes are used by the Quickwin program to send and recieve from the console. The console is launched hidden via CreateProcess with wShowWindow = SW_HIDE. Now that I've given the scenario, here's my problem.

The hidden console's output displays fine on the Quickwin application. When I use WriteFile to send string data to the console, that also appears to work. However, if I press ENTER which is read by key = GetCharQQ(), the console does not respond by accepting the previous string data as the input to continue it's computations. How can I send the ENTER keystroke to the console via the annonymous pipe using WriteFile?

-Richard
0 Kudos
9 Replies
richpauir
Beginner
1,624 Views
Here's some of my code:

.....
type (t_startupinfo) si
type (t_security_attributes) sa
type (t_process_information) pi
.....
character, dimension(bufsize) :: buf
integer(HANDLE) newstdout, newstdin, read_stdout,$
write_stdin
integer(DWORD) exitstatus
integer(DWORD) bread, avail
CHARACTER(1) key / 'A' /
.....
sa%nLength = SIZEOF(sa)
sa%lpSecurityDescriptor = NULL
sa%bInheritHandle = .true.
.....
!Create Input Pipe
If (CreatePipe(newstdin, write_stdin,sa,0) .NE. TRUE) Then
write (4,*) 'Creation of Input Pipe Failed'
Endif
!Create Output Pipe
If (CreatePipe(read_stdout,newstdout,sa,0) .NE. TRUE) Then
write (4,*) 'Creation of Output Pipe Failed'
bret = CloseHandle(newstdin)
bret = CloseHandle(Write_stdin)
Endif
.....
!set to hide the console window
si%dwFlags =IOR(STARTF_USESHOWWINDOW,STARTF_USESTDHANDLES)
si%wShowWindow = SW_HIDE
si%hStdInput = newstdin
si%hStdOutput = newstdout
si%hStdError = newstdout
si%cb= SIZEOF(si)

!Spawn the Console Application
If (CreateProcess(null," Sim.exe"C,null,null,TRUE,Create_New_Console,null,$
null,loc(si),loc(pi)) .NE. TRUE) Then
iret = GetLastError()
write (4,*) 'Spawning of Console Application Failed With Error =',iret
bret = CloseHandle(newstdin)
bret = CloseHandle(Write_stdin)
bret = CloseHandle(newstdout)
bret = CloseHandle(Read_stdout)
Endif
.....
bret = GetExitCodeProcess(pi%hProcess,loc(exitstatus))
do while (exitstatus == STILL_ACTIVE)
......
!Display console application output in Quickwin
bret = Readfile(read_stdout, loc(buf), bufsize, loc(bread), Null)
write (4,9000) buf
9000 format (A$)
......
key = getcharqq()
iret = iachar(key)
!Send console application keystrokes from the Quickwin
if (iret == 13) Then
bret = WriteFile(write_stdin, loc(key),1,loc(bread),Null)
write (4,*) key
Else
bret = WriteFile(write_stdin, loc(key),1,loc(bread),Null)
write (4,9001) key
9001 format (A$)
Endif
.....
bret = GetExitCodeProcess(pi%hProcess,loc(exitstatus))
Enddo
......
bret = CloseHandle(pi.hThread)
bret = CloseHandle(pi.hProcess)
bret = CloseHandle(newstdin)
bret = CloseHandle(Write_stdin)
bret = CloseHandle(newstdout)
bret = CloseHandle(Read_stdout)
.....
0 Kudos
james1
Beginner
1,624 Views
How are you doing the read in the hidden console program?

James
0 Kudos
richpauir
Beginner
1,624 Views
The Quickwin application uses Readfile and Writefile take or add data to the pipes using the handles read_stdout and write_stdin. The other end of the pipes are the standard output and input handles of the console application, newstdout and newstdin.
0 Kudos
james1
Beginner
1,624 Views
The code you posted was from your Quickwin program, correct? In the hidden console program, are you using ReadFile on the standard input handle or are you going through the Fortran RTL (i.e. READ, ACCEPT...)?

James
0 Kudos
richpauir
Beginner
1,624 Views
Yes, the code I posted was from the Quickwin application. The console program is a Fortran executable that my boss developed a few years ago. It was designed to accept text from the user via:
Print*,' Enter variable name. '
Print*,' '
Read(*,30) name
30 Format(A)

My problem is the console is unresponsive when I send text and the ENTER keystroke into the pipe. Reading the console's output via the pipe works fine.
0 Kudos
james1
Beginner
1,624 Views
Try sending a line feed character from the Quickwin program any time you WriteFile a carriage return to the console program, i.e. send CHAR(10)//CHAR(13) not just CHAR(13).

James
0 Kudos
richpauir
Beginner
1,624 Views
I'm following what you are saying. I guess I couldn't use the data buffer that I have defined in my sample code, i.e. CHARACTER(1) key / 'A' /.

What would the code look like to put in the data buffer used by WriteFile?
0 Kudos
james1
Beginner
1,624 Views
Not much change needed. Where you have:
!Send console application keystrokes from the Quickwin
if (iret == 13) Then
bret = WriteFile(write_stdin, loc(key),1,loc(bread),Null)

change to
!Send console application keystrokes from the Quickwin
if (iret == 13) Then
bret = WriteFile(write_stdin, loc(char(10)//key),2,loc(bread),Null)

or something of that sort.

James
0 Kudos
richpauir
Beginner
1,624 Views
James,
If you weren't in Palo Alto I would buy you a round of drinks at the local pub. Thanks for your help, it works great. :)

Richard
0 Kudos
Reply