Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Тихий вызов внешней коммандно-лииевой программы


Автор: szz 8.1.2006, 22:07
Никак не могу наладить такой штуки. То, что в линуксе у меня работало - popen() - в виндах тоже работает, но мелькает черное терминальное окошко. Как от него избавиться?
Поясню все в деталях:
Мне нужно чтобы я мог запустить какую-нибудь command line программу и получить ее вывод себе куда-нибудь.
Например если есть программа, которая делает следующее:

proga.exe:
Код

   main(int argc, char**argv){ 
       printf("Hello, %s!", argv[1]); 
  }


Я пишу другую прогу, которая делает следующее:
Код

   AnsiString proga_exe_stdout = getStdOutFromProgram("proga.exe John");

и вот после этого в переменной proga_exe_stdout должно содержаться "Hello, John!"
то есть мне нужна эта волшебная функция getStdOutFromProgram
И чтоб никаких черных окошек не мелькало!

Автор: Partizan 9.1.2006, 02:02
чел...вот она smile

вот те....вырезка из справки BC++B6:

_popen, _wpopen

Header File

stdio.h

Category

Input/output Routines

Prototype

FILE *_popen (const char *command, const char *mode);

FILE *_wpopen (const wchar_t *command, const wchar_t *mode);

Description

Creates a command processor pipe.

The _popen function creates a pipe to the command processor. The command processor is executed asynchronously, and is passed the command line in command. The mode string specifies whether the pipe is connected to the command processor’s standard input or output, and whether the pipe is to be opened in binary or text mode.

The mode string can take one of the following values:

Value Description

rt Read child command’s standard output (text).
rb Read child command’s standard output (binary).
wt Write to child command’s standard input (text).
wb Write to child command’s standard input (binary).

The terminating t or b is optional; if missing, the translation mode is determined by the external variable _fmode.

Use the _pclose function to close the pipe and obtain the return code of the command.

Return Value

On success, _popen returns a FILE pointer that can be used to read the standard output of the command, or to write to the standard input of the command, depending on the mode string.

On error, it returns NULL.

Автор: szz 9.1.2006, 02:04
Я же говорю: черное окошко консоли мигает!
Как от него избавиться?

Автор: Partizan 9.1.2006, 02:26
ты эту функцию из консольного приложения используешь?

Автор: szz 9.1.2006, 02:28
нет, из GUI!

Автор: Partizan 9.1.2006, 02:32
у меня всё красиво вызывается...
Добавлено @ 02:34
Код

char message[256];
FILE* handle = _popen("E:\\CBuilder6\\Projects\\Новая_папка\\proga.exe John","rt");
fgets(message, sizeof(message), handle);
fputs(message,stdout);

но это из консоли....
Добавлено @ 02:35
А вообще в MSDN по поводу вызова из GUI вот что написано...

Note If used in a Windows program, the _popen function returns an invalid file pointer that will cause the program to hang indefinitely. _popen works properly in a Console application. To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Platform SDK.

Автор: Guest 9.1.2006, 20:35
Из своей GUI
создаешь pipe и передаешь его handle консольному процессу

Код

STARTUPINFO si = { sizeof(si) };
GetStartupInfo(&si);
HANDLE hForWrite=NULL;
HANDLE hForRead=NULL;
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
CreatePipe(&hForRead,&hForWrite,&sa,0);
si.dwFlags|=STARTF_USESTDHANDLES;
si.hStdOutput=hForWrite;
CreateProcess(NULL,commandline,NULL,NULL
    ,TRUE,CREATE_DEFAULT_ERROR_MODE
    |CREATE_NEW_PROCESS_GROUP
    ,NULL
    NULL
    ,&si,&pi)
{
    CloseHandle(hForRead);
}

вывод пойдет не на консоль а в pipe
а с другого конца pipe читаешь в цикле по таймеру или ещё как
Код

PeekNamedPipe(hForRead,0,0,0,&NumberOfBytes,0);
if(0==NumberOfBytes)continue;
PTSTR pbuf=new TCHAR[NumberOfBytes];
ReadFile(hForRead,pbuf,NumberOfBytes,&NumberOfBytes,NULL);

Автор: Guest 9.1.2006, 20:40
чтобы окно консоли не выскакивало на экран
добавь
Код

si.dwFlags|=STARTF_USESHOWWINDOW;
si.wShowWindow=SW_HIDE;

Автор: szz 9.1.2006, 23:59
Вот тут написано:
Код

if(0==NumberOfBytes)continue;

Это в таймере. Но как я узнаю что процесс в pipe завершился чтобы таймер остановить и продолжить работу?

Автор: Partizan 10.1.2006, 20:27
а разве хэндл пайпа по завершении процесса не равен NULL???

Автор: szz 11.1.2006, 07:52
Ок, разобрался smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)