Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Получение инфы из другого процесса


Автор: ershovdz 9.10.2009, 14:54
Есть версия архиватора 7z для командной строки. Хочется из своего процесса запустить в командной строке архивирование и получить инфу, которую архиватор выплевывает в командную строку (прогресс архивирования). Как вариант, можно перенаправить вывод этой инфы в файл и потом его парсить периодически.. Но мне этот вариант чего то не очень нравится. Может еще чего можно придумать ?

Автор: Loki 9.10.2009, 15:23
а собственно что потом делать с выводом? писать логи в своем формате? и зачем это на Си? не проще ли в шел-скрипте запускать?

Автор: Alek86 9.10.2009, 15:35
CreateProcess() принимает указатель на структуру STARTUPINFO (lpStartupInfo), у которого есть поле hStdOutput
туда нужно поместить хендл на свой пайп
подробнее:
http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms686331(VS.85).aspx

Автор: ershovdz 9.10.2009, 16:24
Цитата

а собственно что потом делать с выводом? писать логи в своем формате? 


Мне нужно из asp кода, обратиться по средством COM интерфейса к серверной длл. Причем веб сервер и сама длл могут быть разнесены на разные машины. Эта длл, на той машине, что находится по команде юзера с веб морды, будет запускать архивирование. Архиватор 7z. Мне нужно на веб морде отображать статус архивирования (сколько процентов набежало). Архиватор кидает в командную строку эти самые проценты. Я хочу из длл получить доступ к этим данным, чтобы распарсить и вернуть веб морде, по запросу, прогресс...

Цитата

CreateProcess() принимает указатель на структуру STARTUPINFO (lpStartupInfo.....


Спасибо большое, посмотрю. Только CreateProcess мне не очень нравится тем, что я должен точно знать, где находится архиватор. А через, например, ShellExecuteEx я могу через переменные окружения взять инфу о расположении архиватора.


Автор: ershovdz 9.10.2009, 18:40
Вообщем нашел такой код

Код

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#pragma hdrstop
//#include <condefs.h>
#define bzero(a) memset(a,0,sizeof(a)) //для сокращения писанины
bool IsWinNT() //проверка запуска под NT
{
    OSVERSIONINFO osv;
    osv.dwOSVersionInfoSize = sizeof(osv);
    GetVersionEx(&osv);
    return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
void ErrorMessage(char *str) //вывод подробной информации об ошибке
{
    LPVOID msg;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
        ,NULL
        ,GetLastError()
        ,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)
        ,(LPSTR)&msg
        ,0
        ,NULL);
    printf("%s: %s\n",str,msg);
    LocalFree(msg);
}
//----------------------------------------------------------------------
void main()
{
    char buf[1024]; //буфер ввода/вывода
    STARTUPINFO si;
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd; //структура security для пайпов
    PROCESS_INFORMATION pi;
    HANDLE newstdin,newstdout,read_stdout,write_stdin; //дескрипторы// пайпов
    if (IsWinNT()) //инициализация security для Windows NT
    {
        InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(&sd, true, NULL, false);
        sa.lpSecurityDescriptor = &sd;
    }
    else 
        sa.lpSecurityDescriptor = NULL;
    
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = true; //разрешаем наследование дескрипторов
    if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) //создаем пайп// для stdin
    { 
        ErrorMessage("CreatePipe");
        getch();
        return;
    }
    if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) //создаем пайп// для stdout
    {
        ErrorMessage("CreatePipe");
        getch();
        CloseHandle(newstdin);
        CloseHandle(write_stdin);
        return;
    }
    GetStartupInfo(&si); //создаем startupinfo для
    // дочернего процесса
    /*Параметр dwFlags сообщает функции CreateProcess
    как именно надо создать процесс.
    STARTF_USESTDHANDLES управляет полями hStd*.STARTF_USESHOWWINDOW управляет полем wShowWindow.*/
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout; //подменяем дескрипторы для
    si.hStdInput = newstdin; // дочернего процесса
    //это просто
    //пример,
    //замените на то,
    //что вам нужно
    
    //создаем дочерний процесс
    if (!CreateProcess(NULL, "D:\\7za.exe a D:\\test.zip D:\\test.txt",NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
    {
        ErrorMessage("CreateProcess");
        getch();
        CloseHandle(newstdin);
        CloseHandle(newstdout);
        CloseHandle(read_stdout);
        CloseHandle(write_stdin);
        return;
    }
    unsigned long exit=0; //код завершения процесса
    unsigned long bread; //кол-во прочитанных байт
    unsigned long avail; //кол-во доступных байт
    unsigned long status;
    bzero(buf);
    for(;;) //основной цикл программы
    {
        GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс// не закрыт
        if (exit != STILL_ACTIVE)
            break;
        PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);//Проверяем, есть ли данные для чтения в stdout
        
        if (bread != 0)
        {
            bzero(buf);
            if (avail > 1023)
            {
                while (bread >= 1023)
                {
                    ReadFile(read_stdout,buf,1023,&bread,NULL); //читаем из
                                                                // пайпа stdout
                    printf("%s",buf);
                    bzero(buf);
                }
            }
            else
            {
                ReadFile(read_stdout,buf,1023,&bread,NULL);
                printf("%s",buf);
            }
        }
    }
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(newstdin); //небольшая уборка за собой
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(write_stdin);}


Чего то все равно не выводит нифига. Где затык ?

Автор: jonie 9.10.2009, 19:16
ershovdz, проще воспользоваться прилагаемой к 7z SDK, нежели парсить что-то с консоли имхо

Автор: ershovdz 12.10.2009, 13:28
Цитата(jonie @ 9.10.2009,  19:16)
ershovdz, проще воспользоваться прилагаемой к 7z SDK, нежели парсить что-то с консоли имхо

А есть где-нибудь описание - как им пользоваться ? На оф сайте чего то не нашел..

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