Is it possible to remove the standard withdrawal

I am trying to redirect stdout of an already running process in Windows XP using C #. I know that I can do this if I create a process myself, but for this application I would prefer a “listener” that could just connect to another process.

Is this possible in pure .Net, and if it is even possible with Win32?

thanks

UPDATE: There are several processes that I try to control, and all of them are started by the "gate keeper" process, which will restart these processes if they fail. This makes it difficult for me to redirect forward.

+4
source share
4 answers

It would be pretty easy to do this in Win32 using the Detours Library . You would look at all the WriteFile calls and see if they go to standard outputs. You can also look at console output functions (e.g. WriteConsoleOutput), but they are rarely used, so you probably don't have to worry about using most programs.

Offline I don’t remember whether workarounds support using .NET languages ​​or not. If this is not the case, I suppose you can still use it through P / Invoke, but I don’t think it would be at all ...

Edit: There are various similar (free) libraries. For example, Jeffrey Richter’s book, Advanced Windows, uses one that should work for this purpose. A quick glance shows that its current Windows using C / C ++ still includes the section "Enabling the DLL and Connecting to the API". This probably includes (and an updated version) the same code, which should be sufficient for this kind of work.

+3
source

The SetOut method allows you to redirect standard output.

var sb = new StringBuilder(); using (var writer = new StringWriter(sb)) { Console.SetOut(writer); Console.WriteLine("Hello World"); } var result = sb.ToString(); // The result variable will contain Hello World\r\n 
+1
source

I have no experience with this, but I think you should take a look at this fooobar.com/questions/241632 / .... The next step would be to open the objects associated with these pens for reading, and somehow determine which one is the standard output and error. I doubt that you can grab pens. For example, imagine a scenario where some other process has already redirected standard output and has a descriptor, or maybe even used some IPC so that other processes have this descriptor.

Sorry for not giving a definitive answer, is this possible. I would like to know this myself.

0
source

This will do what you were looking for, I didn't know if you were using C ++, so I just used c-conventions. You need to clean it before you use it. I simply forbade him to also make sure to close the handles to the pipe, or you will leak.

 // RunCmd.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <strsafe.h> int RunCmd(_TCHAR * Command,_TCHAR **OutPut); bool HasTerminated(PROCESS_INFORMATION PI,DWORD *ExitCode); bool HasData(HANDLE H); void ErrorExit(LPTSTR lpszFunction); int _tmain(int argc, _TCHAR* argv[]) { _TCHAR * Buffer; _TCHAR CmdLine[] = _TEXT("Outputter.exe"); RunCmd(CmdLine,&Buffer); wprintf(_TEXT("Buffer from other pgm \n%s"),Buffer); free(Buffer); } int RunCmd(_TCHAR * Command,_TCHAR ** OutPut) { _TCHAR * CpBUff = NULL; STARTUPINFO SI; memset(&SI,0,sizeof(SI)); *OutPut = NULL; SECURITY_ATTRIBUTES SA; SA.nLength = sizeof(SECURITY_ATTRIBUTES); SA.lpSecurityDescriptor = NULL; SA.bInheritHandle = true; HANDLE ReadOutPut, WriteOutPut; if(!CreatePipe(&ReadOutPut,&WriteOutPut,&SA,0)) { wprintf(_TEXT("Error")); } SI.hStdOutput = WriteOutPut; SI.cb = sizeof(STARTUPINFO); SI.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION PI; if (!CreateProcess(NULL,Command,&SA,NULL,true,CREATE_NO_WINDOW,NULL,NULL,&SI,&PI)) { ErrorExit(TEXT("CreateProcess")); } Sleep(500); DWORD ExitCode; char Buffer[512]; _TCHAR ConvBuff[512]; int Total =0; bool Zero; while (!HasTerminated(PI,&ExitCode) & HasData(ReadOutPut)) { ZeroMemory(Buffer,512*sizeof(char)); ZeroMemory(ConvBuff,512 * sizeof(_TCHAR)); DWORD NumBytesRead; ReadFile(ReadOutPut,Buffer,512,&NumBytesRead,NULL); Zero = Total == 0; Total += NumBytesRead +1; *OutPut = ((_TCHAR *) realloc(*OutPut,Total*sizeof(_TCHAR))); if(Zero) { ZeroMemory(*OutPut,Total * sizeof(_TCHAR)); } size_t ConChar; mbstowcs_s(&ConChar,ConvBuff,strlen(Buffer)+1,Buffer,511); StringCchCat(*OutPut,Total,ConvBuff); } CloseHandle(PI.hProcess); CloseHandle(PI.hThread); return ExitCode; } bool HasTerminated(PROCESS_INFORMATION PI,DWORD *ExitCode) { return (STILL_ACTIVE == GetExitCodeProcess(PI.hProcess,ExitCode)); } bool HasData(HANDLE H) { char Buffer[25]; DWORD ReadBytes,TotalBytes,TotalLeft; PeekNamedPipe(H,Buffer,25,&ReadBytes,&TotalBytes,&TotalLeft); return ReadBytes > 0; } void ErrorExit(LPTSTR lpszFunction) { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message and exit the process lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf); MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw); } 
0
source

All Articles