перехват потока ввода/вывода от exec
От: Bekass  
Дата: 21.02.07 07:42
Оценка:
Создаю Win32 приложение...
В нем неообходимо вызвать консольное приложение .
Делаю так

execlp("schtasks.exe"," /query ",NULL);

Но хотелось бы как-то контролировать ввод- вывод от schtasks.exe
Подскажите .... как ?

21.02.07 15:44: Перенесено модератором из 'C/C++' — хотя есть и переносимое решение, popen() — Кодт
Re: перехват потока ввода/вывода от exec
От: sc Россия  
Дата: 21.02.07 07:55
Оценка:
Здравствуйте, Bekass, Вы писали:

B>Создаю Win32 приложение...

B>В нем неообходимо вызвать консольное приложение .
B>Делаю так

B> execlp("schtasks.exe"," /query ",NULL);


B>Но хотелось бы как-то контролировать ввод- вывод от schtasks.exe

B>Подскажите .... как ?
popen ?
Re: перехват потока ввода/вывода от exec
От: 0x8000FFFF Россия  
Дата: 21.02.07 08:03
Оценка:
Read MSDN

BOOL CreateProcess(
  LPCTSTR lpApplicationName,
  LPTSTR lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL bInheritHandles,
  DWORD dwCreationFlags,
  LPVOID lpEnvironment,
  LPCTSTR lpCurrentDirectory,
  LPSTARTUPINFO lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);

typedef struct _STARTUPINFO 
{  
    DWORD cb;  
    LPTSTR lpReserved;  
    LPTSTR lpDesktop;  
    LPTSTR lpTitle;  
    DWORD dwX;  
    DWORD dwY;  
    DWORD dwXSize;  
    DWORD dwYSize;  
    DWORD dwXCountChars;  
    DWORD dwYCountChars;  
    DWORD dwFillAttribute;  
    DWORD dwFlags;  
    WORD wShowWindow;  
    WORD cbReserved2;  
    LPBYTE lpReserved2;  
    HANDLE hStdInput;  
    HANDLE hStdOutput;  
    HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
Re[2]: перехват потока ввода/вывода от exec
От: Bekass  
Дата: 21.02.07 09:57
Оценка:
Здравствуйте, 0x8000FFFF, Вы писали:

FFF>Read MSDN


FFF>
FFF>BOOL CreateProcess(
FFF>  LPCTSTR lpApplicationName,
FFF>  LPTSTR lpCommandLine,
FFF>  LPSECURITY_ATTRIBUTES lpProcessAttributes,
FFF>  LPSECURITY_ATTRIBUTES lpThreadAttributes,
FFF>  BOOL bInheritHandles,
FFF>  DWORD dwCreationFlags,
FFF>  LPVOID lpEnvironment,
FFF>  LPCTSTR lpCurrentDirectory,
FFF>  LPSTARTUPINFO lpStartupInfo,
FFF>  LPPROCESS_INFORMATION lpProcessInformation
FFF>);

FFF>typedef struct _STARTUPINFO 
FFF>{  
FFF>    DWORD cb;  
FFF>    LPTSTR lpReserved;  
FFF>    LPTSTR lpDesktop;  
FFF>    LPTSTR lpTitle;  
FFF>    DWORD dwX;  
FFF>    DWORD dwY;  
FFF>    DWORD dwXSize;  
FFF>    DWORD dwYSize;  
FFF>    DWORD dwXCountChars;  
FFF>    DWORD dwYCountChars;  
FFF>    DWORD dwFillAttribute;  
FFF>    DWORD dwFlags;  
FFF>    WORD wShowWindow;  
FFF>    WORD cbReserved2;  
FFF>    LPBYTE lpReserved2;  
FFF>    HANDLE hStdInput;  
FFF>    HANDLE hStdOutput;  
FFF>    HANDLE hStdError;
FFF>} STARTUPINFO, *LPSTARTUPINFO;

FFF>




ок,
Процесс создал .. CreateProcess, но все же как получить данные вывода этого процесса. есть структура lpProcessInformation , а что делать с ее хэндэлами (запускается консольное приложение)
Re: перехват потока ввода/вывода от exec
От: Сергей Мухин Россия  
Дата: 21.02.07 10:12
Оценка:
Здравствуйте, Bekass, Вы писали:

B>Создаю Win32 приложение...

B>В нем неообходимо вызвать консольное приложение .
B>Делаю так

B> execlp("schtasks.exe"," /query ",NULL);


B>Но хотелось бы как-то контролировать ввод- вывод от schtasks.exe

B>Подскажите .... как ?

Creating a Child Process with Redirected Input and Output

или (если нет MSDN)

Creating a Child Process with Redirected Input and Output
---
С уважением,
Сергей Мухин
Re[2]: перехват потока ввода/вывода от exec
От: sc Россия  
Дата: 21.02.07 10:23
Оценка:
#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[])
{
    char* cmd = "pwd";
    const int buf_size = 512;
    char buf[buf_size];
    FILE* f = popen(cmd, "r");
    if(f)
    {
        while(fgets(buf, buf_size, f))
            cout << buf << endl;
        pclose(f);
    }
    return 0;
}
Re: перехват потока ввода/вывода от exec
От: Аноним  
Дата: 21.02.07 21:12
Оценка:
Здравствуйте, Bekass, Вы писали:

B>Создаю Win32 приложение...

B>В нем неообходимо вызвать консольное приложение .
B>Делаю так

B> execlp("schtasks.exe"," /query ",NULL);


B>Но хотелось бы как-то контролировать ввод- вывод от schtasks.exe

B>Подскажите .... как ?


Делал очень давно, так что реализация возможно хромает.

{
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa;
LPSECURITY_ATTRIBUTES lpsa = NULL;
if (IsWindowsNT())
{
InitializeSecurityDescriptor(&sd,
SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, true, NULL, false);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = true;
sa.lpSecurityDescriptor = &sd;
lpsa = &sa;
}
HANDLE hReadPipe;
HANDLE hWritePipe;
CreatePipe(&hReadPipe, &hWritePipe, lpsa, 25000000);
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
PROCESS_INFORMATION pi;
if(CreateProcess(NULL, ComLine.c_str(), NULL, NULL, TRUE, 0, 0, 0, &si, &pi))
{
CloseHandle(pi.hThread);
switch(WaitForSingleObject(pi.hProcess, 600000))
{
case WAIT_TIMEOUT:
// окончился период ожидания.
// Прекращаем исполнение процесса
TerminateProcess( pi.hProcess, 0xd0000000 );
Data->Message(mUnableExecuteProgram, "");
break;
case WAIT_ABANDONED:
break;
case WAIT_OBJECT_0:
break;
case WAIT_FAILED:
TerminateProcess( pi.hProcess, 0xd0000000 );
Data->Message(mUnableExecuteProgram, "");
break;
}
DWORD BytesRead; //unsigned long
char dest[4000];
bool RdLoopDone = false;
FILE *F;
if ((F = fopen(ScreenFile.c_str(), "wt"))!=NULL)
{
while (!RdLoopDone)
{
memset(dest, 0, 4000);
int i = eof(int(hReadPipe));
ReadFile(hReadPipe, &dest, sizeof(dest), &BytesRead, NULL);
fwrite(&dest, sizeof(char), BytesRead, F);
if (BytesRead < 4000)
RdLoopDone = true;
}
fclose(F);
}
else
{
if (!ScreenFile.IsEmpty())
{
Data->Message(mCantOpenFile, ScreenFile);
Abort = true;
}
}
}
else
{
Data->Message(mUnableExecuteProgram, "");
Abort = true;
}
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
CloseHandle(pi.hProcess);
}


bool IsWindowsNT()
{
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize = sizeof(osv);
GetVersionEx(&osv);
return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
Re[2]: перехват потока ввода/вывода от exec
От: 0x8000FFFF Россия  
Дата: 21.02.07 21:22
Оценка:
Сразу замечание по коду — что это за непонятные константы в коде, которые повторяются...
Вообще то их принято выносить в статические константные переменные...
Re[3]: перехват потока ввода/вывода от exec
От: sc Россия  
Дата: 22.02.07 08:28
Оценка:
Здравствуйте, 0x8000FFFF, Вы писали:

FFF>Сразу замечание по коду — что это за непонятные константы в коде, которые повторяются...

FFF>Вообще то их принято выносить в статические константные переменные...
Правильно, меньше кода -> меньше ошибок.
Обратите внимание на мой примерчик, очень маленький (меньше чем описание одной из структур, которая передается в качестве параметра в createProcess), но все что надо делает
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.