程式很簡單:
程式A:
#include "stdio.h"
int main()
{
int index = 0;
int i = 0;
for (i = 1; i <9988998; i++) {
printf("Current Count is %d\n", index++);
Sleep(10 * 999);
}
}
通過管道獲取stdout時會卡死,究其原因,是因為windows的stdout輸出是全緩沖的,只有緩沖區滿了才會輸出,但我要實作的有一行就輸出一行,在命令列下可以這樣,但用管道一直實作不了,在網上搜了很多代碼,雖然說是異步獲取,但也必須在緩沖區滿了后才能輸出,現在的問題是程式A我無法修改,上面只是個例子,實際功能比它復雜很多,但原理一樣,也沒辦法把windows的命令列改為行緩沖,各位高手有什么好辦法?
uj5u.com熱心網友回復:
輸出換行符,或者fflush 函式強制刷出可以吧?uj5u.com熱心網友回復:
使用PeekNamedPipe查詢管道內的資料,有則讀取,沒有則不讀。主要是防止ReadFile堵塞。uj5u.com熱心網友回復:

應該可以實作,類似 后門系結cmd反彈那種。控制臺的輸入輸出都接管了。
uj5u.com熱心網友回復:
我現在沒有程式a的代碼,上面的代碼只是實作延時輸出的功能,實際輸出也是有延時的,但輸出的內容和我寫的不一樣,是有用的資料。我能做的只能修改管道讀取程式或者修改系統注冊表
uj5u.com熱心網友回復:
僅供參考:#pragma comment(lib,"user32")
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main() {
SECURITY_ATTRIBUTES sa = {0};
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
HANDLE hPipeOutputRead = NULL;
HANDLE hPipeOutputWrite = NULL;
HANDLE hPipeInputRead = NULL;
HANDLE hPipeInputWrite = NULL;
BOOL bTest = 0;
DWORD dwNumberOfBytesRead = 0;
DWORD dwNumberOfBytesWrite = 0;
CHAR szMsg[100];
CHAR szBuffer[256];
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
// Create pipe for standard output redirection.
CreatePipe(&hPipeOutputRead, // read handle
&hPipeOutputWrite, // write handle
&sa, // security attributes
0 // number of bytes reserved for pipe - 0 default
);
// Create pipe for standard input redirection.
CreatePipe(&hPipeInputRead, // read handle
&hPipeInputWrite, // write handle
&sa, // security attributes
0 // number of bytes reserved for pipe - 0 default
);
// Make child process use hPipeOutputWrite as standard out,
// and make sure it does not show on screen.
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput = hPipeInputRead;
si.hStdOutput = hPipeOutputWrite;
si.hStdError = hPipeOutputWrite;
CreateProcess (
NULL, "cmd.exe",
NULL, NULL,
TRUE, 0,
NULL, NULL,
&si, &pi);
// Now that handles have been inherited, close it to be safe.
// You don't want to read or write to them accidentally.
CloseHandle(hPipeOutputWrite);
CloseHandle(hPipeInputRead);
// Now test to capture DOS application output by reading
// hPipeOutputRead. Could also write to DOS application
// standard input by writing to hPipeInputWrite.
sprintf(szMsg, "ver\n");
WriteFile(
hPipeInputWrite, // handle of the write end of our pipe
&szMsg, // address of buffer that send data
strlen(szMsg), // number of bytes to write
&dwNumberOfBytesWrite,// address of number of bytes read
NULL // non-overlapped.
);
while(TRUE)
{
bTest=ReadFile(
hPipeOutputRead, // handle of the read end of our pipe
&szBuffer, // address of buffer that receives data
256, // number of bytes to read
&dwNumberOfBytesRead, // address of number of bytes read
NULL // non-overlapped.
);
if (!bTest){
sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
printf("%s",szMsg);
break;
}
// do something with data.
szBuffer[dwNumberOfBytesRead] = 0; // null terminate
printf("%s",szBuffer);
if ('>'==szBuffer[dwNumberOfBytesRead-1]) break;
}
sprintf(szMsg, "chcp\nexit\n");
WriteFile(
hPipeInputWrite, // handle of the write end of our pipe
&szMsg, // address of buffer that send data
strlen(szMsg), // number of bytes to write
&dwNumberOfBytesWrite,// address of number of bytes read
NULL // non-overlapped.
);
while(TRUE)
{
bTest=ReadFile(
hPipeOutputRead, // handle of the read end of our pipe
&szBuffer, // address of buffer that receives data
256, // number of bytes to read
&dwNumberOfBytesRead, // address of number of bytes read
NULL // non-overlapped.
);
if (!bTest){
sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
printf("%s",szMsg);
break;
}
// do something with data.
szBuffer[dwNumberOfBytesRead] = 0; // null terminate
printf("%s",szBuffer);
}
// Wait for CONSPAWN to finish.
WaitForSingleObject (pi.hProcess, INFINITE);
// Close all remaining handles
CloseHandle (pi.hProcess);
CloseHandle (hPipeOutputRead);
CloseHandle (hPipeInputWrite);
return 0;
}
//C:\test>test
//Microsoft Windows [版本 5.2.3790]
//(C) 著作權所有 1985-2003 Microsoft Corp.
//
//C:\test>ver
//
//Microsoft Windows [版本 5.2.3790]
//
//C:\test>chcp
//活動的代碼頁: 936
//
//C:\test>exit
//Error #109 reading pipe.
//C:\test>
uj5u.com熱心網友回復:
今天遇到同樣的問題,找遍了,沒有在網上發現解決方案,抱著試試看的想法,終于找到了最好的解決方案。無須命名管道,只需在讀取前加上GetFileSizeEx判斷即可,代碼如下:
char buf[ 1024 ];
LARGE_INTEGER off;
::GetFileSizeEx( z_stdoutRd, &off );
if ( off.LowPart || off.HighPart )
{
DWORD readSize = 0;
BOOL b = ::ReadFile( z_stdoutRd, buf, 1024, &readSize, NULL );
buf[ readSize ] = 0;
::OutputDebugStringA( buf );
}
uj5u.com熱心網友回復:
學習了。最討厭緩沖了。
uj5u.com熱心網友回復:
你要再另一端讀,輸入才不會卡。寫滿了就不會再寫了,除非是異步io轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/62479.html
標籤:進程/線程/DLL
