Форум: "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.036 c