问题
My question is quite simple, but the solution seems absolutely impossible for me to find.
I have a dedicated game server (JEDI ACADEMY JAMPDED), which is a console application. It writes some information continously and I want to handle the data somehow. It would be easy if I could read the output of it with external.
Problem: It does not write to Standard Output, so can't be piped with batch file and popen does not work also.
So I wanted to do with WINAPI. I was able to create the process, but still can't read the output.
I tried these:
How do I call ::CreateProcess in c++ to launch a Windows executable?
CreateProcess and CreatePipe to execute a process and return output as a string in VC++
AND the MSDN official example, but still nothing.
This is the jampded.exe:

I got a visual-basic code from my friend, who reads ConsoleInput from Ingame, so I'm pretty sure, that it is possible to read the console:
SNIPPET:
Global hWnd = FindWindow_(#Null,"Jedi Knight Academy MP Console") ;console window
Global hWnd2 = FindWindow_(#Null,"Jedi Knight®: Jedi Academy (MP)") ;actual game window
Global inputhWnd = FindWindowEx_(hwnd,0,"edit",0) ;the one to send stuff to
Global consolehWnd = FindWindowEx_(hwnd,inputhWnd,"edit",0) ;the one to read the console from
Procedure checkConsole()
Protected wholetext.s, oldtext.s,text.s, checkname.s
Repeat
wholetext = getText()
If wholetext
text = StringField(wholetext,CountString(wholetext,#CRLF$),#CRLF$)
If oldtext <> text
oldtext = text
analyseConsole(@text)
EndIf
EndIf
Delay(20)
writePreferences()
Until quit
EndProcedure
Procedure.s getText()
Protected wholetext.s
If hWnd And hWnd2
If Not inputhWnd Or Not consolehWnd
inputhWnd = FindWindowEx_(hWnd,0,"edit",0)
consolehWnd = FindWindowEx_(hWnd,inputhWnd,"edit",0)
EndIf
length = SendMessage_(consolehWnd, #WM_GETTEXTLENGTH, 0, 0)
wholetext = Space(length)
SendMessage_(consolehWnd,#WM_GETTEXT,length + SizeOf(Character),@wholetext)
ProcedureReturn wholetext
Else
If FindWindow_(#Null,"Jedi Knight Academy MP Console")
hWnd = FindWindow_(#Null,"Jedi Knight Academy MP Console")
hWnd2 = FindWindow_(#Null,"Jedi Knight®: Jedi Academy (MP)")
inputhWnd = FindWindowEx_(hwnd,0,"edit",0)
consolehWnd = FindWindowEx_(hwnd,inputhWnd,"edit",0)
EndIf
ProcedureReturn ""
EndIf
If @wholetext > 0
FreeMemory(@wholetext)
EndIf
EndProcedure
Maybe this could help me and others too :)
回答1:
Hans Passant was right. It does not write to stdout, but I could fix it with assembly. So he was not right in that.
After this the output was unsynced, but it could be successfully fixed with exchanging a jump to nops. More: stackoverflow.com/questions/23811572/writefile-function-with-assembly-debugging-syncing
So sum everything up:
It is not just for Jedi Academy Dedicated Server, it can be useful for any binary file that stores output, but not to STDOUT.
Changing WriteFile function to write to STDOUT (-11 is stdout):

Fix syncing problem:

It is for JampDed 1.00, so if you want to use it for another version of JK, or for another game, you must find these addresses yourself. Best practise (in my opinion) if you go call by call deeper in the code. You may start from any message you find, then go deeper.
I have logged the whole debugging process this way:
004429a7 is (call 0043d440)
- 0043d44e (call 00422720)
-- 004227dD (call edx) - 2008F1B0
--- 2008f103 (call 2008cad0)
---- 2008c4d0
----- 2008c569 (call 2008b030)
------ 200a25f7 DWORD PTR DS:[20106A28] - 00422540
------- 0042254b (CALL DWORD PTR DS:[ECX+4]) - 0043d590
-------- 0043d8aa (call 0040fb40)
--------- 0040FC39 (call 0044b7a0)
---------- 0044b66c (call 004964dd)
----------- 00496500 (call 0049a4ba)
------------ 0049a4cd (call 00497d66)
------------- 00497d92 (call 0049e18c)
-------------- 0049e26f (CALL DWORD PTR DS:[4A715C])
And if you notice the last one is where WriteFile is located. And 2 before that is where the logsync stuff is located
So now
jampDed.exe | stdout.exe
works, and you can start creating your own mod for the server easily. Or anything you want. :)
来源:https://stackoverflow.com/questions/19298861/reading-console-buffer-output-c