Хорошо, я задал несколько вопросов о разных аспектах попытки выполнить то, что я хочу сделать. На этот раз у меня большие проблемы, только чтение из именованного канала. Я думаю, что собрал достаточно информации, чтобы завершить проект, над которым я работаю, если я смогу правильно настроить его. Я включу весь соответствующий код ниже, но моя миссия такова: читайте вывод (непрерывно) из программы, которую я сделал , а не пишите и публикуйте ее в WinAPI. Поэтому моя проблема заключается в том, что я только что переключился с анонимных каналов на именованные каналы, и у меня возникают проблемы с их правильной настройкой, поэтому я могу получить информацию. У меня есть настройка рамки, основанная на примере из MSDN.Асинхронный ввод-вывод с именованными трубами WinAPI
#define WAIT_TIME 2 // 2s
#define INSTANCES 4 // Number of threads
#define CONNECT_STATE 0
#define READ_STATE 1
#define WRITE_STATE 2
#define WORLDRD 0
#define WORLDWR 1
#define WORLDINRD 2
#define WORLDINWR 3
#define BUFSIZE 0x1000 // Buffer size 4096 (in bytes)
#define PIPE_TIMEOUT 0x1388 // Timeout 5000 (in ms)
void Arc_Redirect::createProcesses()
{
TCHAR programName[]=TEXT("EXEC_PROGRAM.exe");
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL bSuccess = FALSE;
ZeroMemory(hEvents,(sizeof(hEvents)*INSTANCES));
ZeroMemory(outStd,(sizeof(PIPE_HANDLES)*INSTANCES));
// Prep pipes
for(int i=0;i<INSTANCES;i++)
{
hEvents[i] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if(hEvents[i] == NULL)
throw "Could not init program!";
outStd[i].o1.hEvent = hEvents[i];
outStd[i].hPipeInst = ::CreateNamedPipe(
TEXT("\\\\.\\pipe\\arcworld"), PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, BUFSIZE*sizeof(TCHAR), BUFSIZE*sizeof(TCHAR), PIPE_TIMEOUT, NULL);
if(outStd[i].hPipeInst == INVALID_HANDLE_VALUE)
throw "Could not init program!";
outStd[i].pendingIO = getState(outStd[i].hPipeInst,&outStd[i].o1);
outStd[i].dwState = outStd[i].pendingIO ?
CONNECT_STATE : READ_STATE;
}
// Set stuff up
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.hStdError = outStd[WORLDRD].hPipeInst;
si.hStdOutput = outStd[WORLDRD].hPipeInst;
si.hStdInput = outStd[WORLDINWR].hPipeInst;
si.dwFlags |= STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES|FILE_FLAG_OVERLAPPED;
// Start our process with the si info
CreateProcess(programName,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
}
BOOL Arc_Redirect::getState(HANDLE hPipe, LPOVERLAPPED lpo)
{
BOOL connected, pendingIO = FALSE;
// Overlap connection for this pipe
connected = ::ConnectNamedPipe(hPipe,lpo);
if(connected)
throw "ConnectNamedPipe(); failed!";
switch(GetLastError())
{
case ERROR_IO_PENDING:
pendingIO = TRUE;
break;
case ERROR_PIPE_CONNECTED:
if(SetEvent(lpo->hEvent))
break;
default:
throw "ConnectNamedPipe(); failed!";
break;
}
return pendingIO;
}
outStd [СЛУЧАИ] определяется как PIPE_HANDLES (пользовательские структуры), которая находится ниже
typedef struct
{
HANDLE hPipeInst;
OVERLAPPED o1;
TCHAR chReq[BUFSIZE];
TCHAR chReply[BUFSIZE];
DWORD dwRead;
DWORD dwWritten;
DWORD dwState;
DWORD cbRet;
BOOL pendingIO;
} PIPE_HANDLES, *LPSTDPIPE;
Теперь отсюда, где я получаю немного потерял. Я не знаю, куда идти. Я попытался использовать цикл в примере MSDN, но он не работал должным образом для того, что я ищу. Мне нужно взять конец считывания и получить информацию (опять же, непрерывно), а также открыть конец записи, когда мне может понадобиться записать ее. У кого-нибудь есть идеи? Я пытаюсь сделать ReadFile(), как я бы сделал с анонимным каналом, но он, похоже, не работает одинаково.
Также обратите внимание: код немного неряшлив, потому что я работал с ним, поэтому извиняюсь. Я определенно буду убирать его после того, как я получу это для правильной работы.
В чем проблема, связанная с ReadFile? Именованные трубы и анонимные трубы работают одинаково, когда они открыты. –
Я переключился на анонимные каналы для своих целей, однако, похоже, это проблема с обоими.Ему нужно дождаться окончания передачи данных для отправки каких-либо данных, поэтому я продолжу работу над ней. – RageD