![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() итак. есть некая утилита которая работает через командную строку.
моё приложение написанное на дельфи посылает ей команды, используя найденную в сети функцию GetDosOutput. если команда успешно отработана,то утилита ничего не возвратит,то есть пустую строку.если же при выполении команды произошла ошибка то вернется сообщение об ошибке. Соответственно я проверяю возвращаемый рез-тат и если он пустой,значит команда успешна,значит моя прога продолжает что либо делать. Но вот незадача,в одном месте эта сторонняя утилита завершается с ошибкой,то есть не просто выводит в ответ сообщение об ошибке что немогу выполнить команду, а резко завершается,сбой какойто.и в ответ моя функция не получает сообщение с ошибкой а получает пустой результат, и я незнаю как определить что это пустой результат в случае успешного выполнения команды,или же это пустота изза того что процесс утилиты резко завершился. Может как то можно проверить что процесс вызванный функцией GetDosOutput завершился преждевременно. И ещё,при такой ошибке на экране появляется сообщение от винды7 что эта утилита завершилась (не моя прога а сторонняя утилита) Возникшая проблема привела к прекращению работы программы. Windows закроет эту программу, а если есть известный способ устранения проблемы, уведомит вас об этом. - можно ли это сообщение както скрыть от глаз юзера? вот сама функция Код:
function GetDosOutput(CommandLine,Parametrs:string): string; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; StdOutPipeRead, StdOutPipeWrite: THandle; WasOK: Boolean; Buffer: array[0..255] of Char; BytesRead: Cardinal; WorkDir, 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+' '+Parametrs), nil,nil,True,0,nil,PChar(WorkDir),SI,PI); // Теперь, когда дескриптор получен, для безопасности закрываем запись. // Нам не нужно, чтобы произошло случайное чтение или запись. CloseHandle(StdOutPipeWrite); // если процесс может быть создан, то дескриптор, это его вывод if not WasOK then begin Line:='Could not execute'; end else try // получаем весь вывод до тех пор, пока DOS-приложение не будет завершено Line := ''; repeat //считывает ответ после выполнения команды // читаем блок символов (могут содержать возвраты каретки и переводы строки) WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil); // есть ли что-нибудь ещё для чтения? if BytesRead > 0 then begin // завершаем буфер PChar-ом Buffer[BytesRead] := #0; //Form1.Memo1.Lines.Add(Buffer); Line := Line + Buffer; end; until not WasOK or (BytesRead = 0); // ждём, пока завершится консольное приложение WaitForSingleObject(PI.hProcess, INFINITE); finally // Закрываем все оставшиеся дескрипторы CloseHandle(PI.hThread); CloseHandle(PI.hProcess); end; finally result:=Line; CloseHandle(StdOutPipeRead); end; end; |