Работа С Командной Строкой
#1
Отправлено 12 сентября 2007 - 12:27
Тестируемая программа написана на java
язык скрипта Delphi
Тут возникла необходимость получить данные которые выводяться в командню строку, кто нить знает как это сделать???
Я пытался сделать кодом Delphi который нашел в инете:
procedure com;
var ProcInfo: TProcessInformation;
StartupInfo: TStartupInfo;
SecAtrtrs: TSecurityAttributes;
hOut: THandle;
begin
with SecAtrtrs do
begin
nLength := SizeOf(TSecurityAttributes);
lpSecurityDescriptor := nil;
bInheritHandle := true; // ВОТ ОНО !!! Наша рукоятка будет НАСЛЕДУЕМОЙ
end;
// Создаем файл в который и будем переназначать StdOut
// Например, с такими настройками, вы можете их изменить под свои нужды
hOut := CreateFile('c:\MyStdOut.txt', GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hOut = INVALID_HANDLE_VALUE) then RaiseLastWin32Error;
GetStartupInfo(StartupInfo);
with StartupInfo do
begin
wShowWindow := SW_HIDE; // не показывать окно
dwFlags := dwFlags or STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
hStdOutput := hOutDup; // присваиваем рукоятку на свой файл
end;
// для примера будем запускать [c:\program files\Borland\Delphi5\Bin]grep.exe с ключом '?'
// Вызов CreateProcess с флагом bInheritHandles = TRUE !!!
Win32Check(CreateProcess(nil, 'ipconfig /all', nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, StartupInfo, ProcInfo));
// ждем пока наш процесс отработает
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
Win32Check(CloseHandle(ProcInfo.hProcess));
//если вы больше ничего не хотите делать с файлом, в который перенаправили StdOut, то закроем его
Win32Check(CloseHandle(hOut));
end;
но testcomplet при компиляции даёт ошибку, хотя в редакторе ошибки не идентифицируются
Если кто делал что нить подобное напишите пожалуста
#2
Отправлено 12 сентября 2007 - 15:33
с помощью добавления к консоли ">имяф_файла" - вывод будет направлен в файл.
Хотя скорее всего я просто не до конца вник в текст
#3
Отправлено 12 сентября 2007 - 18:44
Можете использовать ClrBridge, чтобы сделать это через .NET. Вот так:
procedure Test; var p, output; begin p := dotNET.System_Diagnostics.Process.zctor(); p.StartInfo.FileName := 'c:\Windows\System32\cmd.exe'; p.StartInfo.Arguments := '/c ipconfig'; p.StartInfo.UseShellExecute := False; p.StartInfo.RedirectStandardOutput := True; p.Start; while not p.HasExited do Delay(100); output := p.StandardOutput.ReadToEnd(); Log.Message(output); end;
Чтобы этот код заработал, надо добавить ассемблю System.dll в ваш проект TestComplete'а. Для этого дважды щёлкните на имени проекта в Project Explorer, откройте страницу Properties редактора проекта и в опциях 'CLR Bridge' нажмите 'Browse GAC...'.
Дмитрий
#4
Отправлено 13 сентября 2007 - 05:26
А не проще работать с файлом после вывода?
с помощью добавления к консоли ">имяф_файла" - вывод будет направлен в файл.
Хотя скорее всего я просто не до конца вник в текст
Не проще т.к. команды пишу unuix серверу а он их не поймёт
#5
Отправлено 13 сентября 2007 - 05:33
Здравствуйте.
Можете использовать ClrBridge, чтобы сделать это через .NET. Вот так:procedure Test; var p, output; begin p := dotNET.System_Diagnostics.Process.zctor(); p.StartInfo.FileName := 'c:\Windows\System32\cmd.exe'; p.StartInfo.Arguments := '/c ipconfig'; p.StartInfo.UseShellExecute := False; p.StartInfo.RedirectStandardOutput := True; p.Start; while not p.HasExited do Delay(100); output := p.StandardOutput.ReadToEnd(); Log.Message(output); end;
Чтобы этот код заработал, надо добавить ассемблю System.dll в ваш проект TestComplete'а. Для этого дважды щёлкните на имени проекта в Project Explorer, откройте страницу Properties редактора проекта и в опциях 'CLR Bridge' нажмите 'Browse GAC...'.
Спасибо большое за ответ.
Но у меня правда чего не получается:
Поставил себе .NET Framework 3.0
Сделал переконфигурацию testcomplete
потом всё так как вы написали , но он ругается что не знает такого "System_Diagnostics" до этого ругался на "dotNET", я уже внёс в список всё dll какие только были, значиться у меня её нет? как можно её найти?
Подскажите пожалуста
#6
Отправлено 13 сентября 2007 - 05:44
я тут нашёл ещё...
так не пойдёт заменить ту строку??
p := dotNET.System.System_Diagnostics_Process.ctor();
#7
Отправлено 13 сентября 2007 - 06:13
и вроде всё заработало только вот я не пойму как организовать такое действие:
Я запускаю cmd через testcomplete и данные тоже ввожу только им а вот полученыы результат уже и выводить
мне надо не одну не две команды написать , нужно организовать целую серию запросов-ответов
#8
Отправлено 13 сентября 2007 - 11:31
Можно послать несколько запросов, а потом, когда приложение закроется, прочитать все ответы сразу.
procedure Test; var p, input, output; begin p := dotNET.System_Diagnostics.Process.zctor(); p.StartInfo.FileName := 'c:\Windows\System32\cmd.exe'; p.StartInfo.UseShellExecute := False; p.StartInfo.RedirectStandardOutput := True; p.StartInfo.RedirectStandardInput := True; p.Start; input := p.StandardInput; output := p.StandardOutput; input.WriteLine('ver'); input.WriteLine('dir'); input.WriteLine('ipconfig'); input.WriteLine('quit'); while not p.HasExited do Delay(100); while not output.EndOfStream do Log.Message(output.ReadLine()); end;
Конечно, хотелось бы, чтобы ответы читались сразу после запросов. Однако, если запросить у потока StandardOutput строку, в которой производится запрос на ввод (например, командная строка), то методы чтения потока "подвиснут", пока приложение не напишет что-либо в поток. А оно не напишет, пока не пошлёшь строку в StandardInput. Это можно разрулить подписавшишь на соответствующее событие или запустив чтение и запись в разных нитях (threads), однако ни то ни другое нельзя сделать из скрипта.
Как вариант, можно читать из потока StandardOutput по символу, пока не увидите приглашение коммандной строки (по умолчанию '>', но можно изменить коммандой prompt).
Дмитрий
#9
Отправлено 17 сентября 2007 - 04:21
Кстати интересный факт теперь у меня ваша строка p := dotNET.System_Diagnostics.Process.zctor();, работает, а моя(которая ещё в пятницу отрабатывала) p := dotNET.System.System_Diagnostics_Process.ctor(); не хотит :)
#10
Отправлено 17 сентября 2007 - 05:23
Как можно это обойти? или телнету нельзя так же команты передавать и читать как cmd ?
#11
Отправлено 17 сентября 2007 - 10:20
Разные имена у функций могут быть из-за того, что не используете плагин 'TestComplete 3 Compatibility' (он у меня был включен, когда я пример делал).
Что касается telnet, я думаю разницы быть не должно. Убедитесь, что вы перенаправили и поток ввода и поток вывода перед запуском процесса:
p.StartInfo.UseShellExecute := False;
p.StartInfo.RedirectStandardOutput := True;
p.StartInfo.RedirectStandardInput := True;
Дмитрий
#12
Отправлено 17 сентября 2007 - 10:46
Вот код процедуры всё также
procedure com;
var
p, input, output;
begin
p := dotNET.System_Diagnostics.Process.zctor();
p.StartInfo.FileName := 'C:\WINDOWS\system32\telnet.exe';
p.StartInfo.UseShellExecute := False;
p.StartInfo.RedirectStandardOutput := True;
p.StartInfo.RedirectStandardInput := True;
p.Start;
input := p.StandardInput;
output := p.StandardOutput;
input.WriteLine_11('?');
while not p.HasExited do
Delay(100);
while not output.EndOfStream do
Log.Message(output.ReadLine());
end;
окошко мелькает и исчезает, хотя cmd хотя бы на экране остаётся, поучается что запуск идёт неправильно может дело в dll System_Diagnostics ведь у нёё название содержит смысл "Диагностика" что как то с telnet -ом не вяжется???
вообщем я завяз и думаю может написать на Delphi элементарнейший клиент и из него уже таскать данные???
#13
Отправлено 17 сентября 2007 - 13:04
У меня тоже telnet так себя ведёт. Я посмотрел -- у него Exit Code равен '-1'. Это не нормальный код, нормальный это '0'. Не могу сказать, что именно это значит. Возможно, какие-то настйроки безопасности системы не дают запустить telnet с параметром UseShellExecute = false или с перенаправлением потоков.
В данном случае могу предложить посылать команды в окно telnet используя Wnd.Keys, а читать их через буфер обмена. Другой вариант -- написать простую программу, как вы сами предложили.
Дмитрий
Количество пользователей, читающих эту тему: 1
0 пользователей, 1 гостей, 0 анонимных