Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];

Вниз

Работа с консольным приложеним   Найти похожие ветки 

 
Virtual GOD   (2004-07-17 02:05) [0]

Здравствуйте.
 Вот, у меня есть пара вопросов по работе с консольным приложением.
 1. Как можно перехватывать вывод программы? (без использования сдвигов в cmd для сохранения в файл)
 2. Как можно подавать приложению на ввод данные?
 3. Как завершать такое приложение?
 4. И как ограничивать права при запуске конс. приложения? т.е., запускается, но с ограничениями, к примеру, на работу с винтом, доступ к реестру и т.п.... Запускать под пользователем с опред. привелегиями? Если да, то как? Или же, мне говорили о т.н. "песочнице"... Что оно из себя представляет и как с ней работать? если можно, то дайте ссылочку или примерчик небольшой...
Все это мне необходимо для написания программы-судьи олимпиадных задач по программированию, как на acm.uva.es и т.п. Если будут какие-то различия при использовании разных ОС-ей, то, лучше, ориентироваться на 2000-xp-2003 Server
Заранее, всем спасибо.
С Уважением, V.G.


 
Cobalt ©   (2004-07-17 09:18) [1]

1, 2 - запускать прогу через CreateProcess, и там подменять ей stdi/o (кажый месяц как минимум поднимается этот вопрос)
3 - смотря по интерфейсу, который предоставляет программа.
4) - CreateProcessAsUser+LogonUser. А пользователю уже можно настроить права для доступа к диску (только NTFS) и реестру(см. Regedit).


 
Virtual GOD   (2004-07-17 17:13) [2]

ага, понятно... спасибо за ответ. А как подменять stdi/stdo? На этом сайте так и не нашел, на Яндексе и Гугле тоже... Можно ссылочку? И что значит, смотря по интрфейсу, который предоставляет программа? Все остальное, вроде понятно...


 
Никто ©   (2004-07-17 19:02) [3]

http://www.sources.ru/delphi/system/delphi_pipes.shtml


 
Никто ©   (2004-07-17 19:03) [4]

Удалено модератором


 
xShadow ©   (2004-07-19 08:57) [5]

Function GetDosOutput( const CommandLine,
                            WorkDir    : String;
                        var ResultCode : Cardinal ): String;
var StdOutPipeRead, StdOutPipeWrite: THandle;
   SA                             : TSecurityAttributes;
   SI                             : TStartupInfo;
   PI                             : TProcessInformation;
   WasOK                          : Boolean;
   Buffer                         : array[0..255] of Char;
   BytesRead                      : Cardinal;
   Line                           : String;
Begin
   Application.ProcessMessages;
   With SA do
   Begin
      nLength := SizeOf( SA );
      bInheritHandle := True;
      lpSecurityDescriptor := nil;
   end;
   // создаём пайп для перенаправления стандартного вывода
   CreatePipe( StdOutPipeRead,  // дескриптор чтения
               StdOutPipeWrite, // дескриптор записи
               @SA,              // аттрибуты безопасности
               0                // количество байт принятых для пайпа - 0 по умолчанию
              );
   try
    // Создаём дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,
    // а так же проверяем, чтобы он не показывался на экране.
    with SI do
    Begin
       FillChar( SI, SizeOf( SI ), 0 );
       cb := SizeOf( SI );
       dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
       wShowWindow := SW_HIDE;
       hStdInput := GetStdHandle( STD_INPUT_HANDLE ); // стандартный ввод не перенаправляем
       hStdOutput := StdOutPipeWrite;
       hStdError := StdOutPipeWrite;
    end;

    // Запускаем компилятор из командной строки
    //WorkDir := ExtractFilePath(CommandLine);
    WasOK := CreateProcess( nil,
                            PChar( CommandLine ),
                            nil,
                            nil,
                            True,
                            0,
                            nil,
                            PChar( WorkDir ),
                            SI,
                            PI );
    // Теперь, когда дескриптор получен, для безопасности закрываем запись.
    // Нам не нужно, чтобы произошло случайное чтение или запись.
    CloseHandle( StdOutPipeWrite );
    // если процесс может быть создан, то дескриптор, это его вывод
    if not WasOK then
     raise Exception.Create( "Ошибка выполнения или компиляции: " +
            Chr( 10 ) + Chr( 13 ) + CommandLine )
    else
      try
        // получаем весь вывод до тех пор, пока DOS-приложение не будет завершено
        Line := "";
        Repeat
           // читаем блок символов (могут содержать возвраты каретки и переводы строки)
           WasOK := ReadFile( StdOutPipeRead, Buffer, 255, BytesRead, nil );
           // есть ли что-нибудь ещё для чтения?
           if BytesRead > 0 then
           Begin
              // завершаем буфер PChar-ом
              Buffer[BytesRead] := #0;
              // добавляем буфер в общий вывод
              Line := Line + Buffer;
           end;
           Application.ProcessMessages;
        Until not WasOK or ( BytesRead = 0 );
        // ждём, пока завершится консольное приложение
        WaitForSingleObject( PI.hProcess, INFINITE );
        ResultCode := 0;
        GetExitCodeProcess( PI.hProcess, ResultCode );
      finally
        // Закрываем все оставшиеся дескрипторы
        CloseHandle( PI.hThread );
        CloseHandle( PI.hProcess );
      end;
   finally
     Result := Line;
     CloseHandle( StdOutPipeRead );
 end;
end;


Ещё как вариант!


 
xShadow ©   (2004-07-19 09:01) [6]

Использовать можно так!
ListBox1.Items.Text := GetDosOutput( "c:\command.com",
                                    "c:\",
                                    DosResCode );


 
DarkLord   (2004-07-20 01:54) [7]

А обратную задачу можно? Т.е. написать текст и чтобы он вывелся в консольном приложении. Вопрос в том, что таких приложений может быть запущено ...надцать, а вывести необходимо в конкретном.
Если не сложно, то с примерчиком плиз. Личные страдания пока успехом не увенчались :)



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.032 c
1-1092292319
Fynjy
2004-08-12 10:31
2004.08.29
Фокус


1-1092670055
ЮрийК
2004-08-16 19:27
2004.08.29
Почему получается исключение?


1-1092073269
KOMbI4
2004-08-09 21:41
2004.08.29
Встроенный Ассемблер


1-1092504966
начинающий
2004-08-14 21:36
2004.08.29
Матрица


14-1092044143
Серж
2004-08-09 13:35
2004.08.29
Как склеить 2 exe-шника?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский