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

Вниз

WinExec непонятка   Найти похожие ветки 

 
Besa   (2001-09-11 11:11) [0]

Доброго времени суток! Непонятка вот в чем: WinExec в примере приведенном ниже работает нормально
WinExec("arj a c:\temp\Db.arj c:\temp\Db.txt", SW_SHOW)
но если я пытаюсь передать переменную(см. ниже)
1 вар.
WinExec("arj a c:\temp\Db"+ ORG + ".arj c:\temp\Db" + "ORG" + ".txt", SW_SHOW)
2 вар.
WinExec(Str1, SW_SHOW)
выбивает ошибку:
[Error] Unit1.pas(88): Incompatible types: "String" and "PChar"
причем DeleteFile работает нормально
пример кода:

var DUBL, ORG, Str1:String;
i,y:Integer;
F :System.Text;

begin
Query1.Active:=True;
Query1.First;
ORG:=Query1.FieldByName("pr_org").AsString;
Str1:="arj a c:\temp\Db" + ORG + ".arj c:\temp\Db" + ORG + ".txt";

if WinExec("arj a c:\temp\Db"+ ORG + ".arj c:\temp\Db" + "ORG" + ".txt", SW_SHOW) < 32
then
begin

end
else
if deletefile("c:\temp\Db"+ORG+".txt")
then
ShowMessage( DELETE !")
else
ShowMessage(" Not DELETE !");
подскажите,плс, в чем я не прав


 
Digitman   (2001-09-11 11:29) [1]

WinExec(PChar(Str1), SW_SHOW)

а что, по твоему разницы между string и PChar нет никакой ? глубоко заблуждаешься !


 
Юрий Зотов   (2001-09-11 11:32) [2]

В том, что передаете параметр типа string там, где требуется PChar. В случае константы компилятор все делает сам, а в случае переменной надо использовать явное приведение типа:

WinExec(PChar("arj a c:\temp\Db" + ORG + ".arj c:\temp\Db" + "ORG" + ".txt"), SW_SHOW);

WinExec(PChar(Str1), SW_SHOW);


 
Besa   (2001-09-11 11:43) [3]

>All
Cпасибо!
Вы уж простите неуча, что отвлекаю... :)


 
Besa   (2001-09-11 19:09) [4]

>All
Опять неуч беспокоит
WinExec возвращает код завершения > 31, то выполнено...
вопрос:
1)отработала данная вызванная программа(в смысле ждет ли завершения выполнения внешней проги)? т.е. в данном примере возможно ли удаление раньше архивации?
2) как можно получить errorlevel от внешней программы
3) хотелость бы узнать - это и все коды завершения возвращаемые сабжем
0 The system is out of memory or resources.
ERROR_BAD_FORMAT The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
ERROR_FILE_NOT_FOUND The specified file was not found.
ERROR_PATH_NOT_FOUND The specified path was not found.
Заранее благодарен


 
Юрий Зотов   (2001-09-11 22:40) [5]

1. Нет, не ждет. Просто запускает - и все, а что будет дальше - никому не известно.

2. Получить хэндл ее процесса, а затем дождаться ее завершения и вызвать GetExitCodeProcess.

3. В хелпе других кодов нет. Надо полагать, это все.

Похоже, Вам нужно ипользовать функцию CreateProcess, которая позволяет легко совместить все "в одном флаконе". Вот рабочий пример запуска внешней программы с ожиданием ее завершения, получением кода возврата и вызовом обработчика события при завершении.

unit Unit1;

interface

uses
SysUtils, Classes, Controls, Forms, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure ThreadFinished(Sender: TObject);
end;

var
Form1: TForm1;

implementation

uses
Unit2;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
// Создаем и настраиваем второй поток. Он запустит внешнюю программу,
// дождется ее завершения, вызовет наш обработчик и даст код возврата.
with TMyThread.Create(False) do
begin
CommandLine := "Notepad.exe AutoExec.bat"; // Подставьте свое
WorkingDirectory := "C:\"; // Подставьте свое
OnTerminate := ThreadFinished
end
end;

procedure TForm1.ThreadFinished(Sender: TObject);
begin
// Внешняя программа завершилась. Второй поток больше не нужен.
with TMyThread(Sender) do
begin
Caption := IntToStr(ExitCode);
Free
end
end;

end.

=========================================

unit Unit2;

interface

uses
Windows, Classes;

type
TMyThread = class(TThread)
private
FCommandLine: string;
FWorkingDirectory: string;
FExitCode: DWORD;
protected
procedure Execute; override;
public
property CommandLine: string read FCommandLine write FCommandLine;
property WorkingDirectory: string read FWorkingDirectory write FWorkingDirectory;
property ExitCode: DWORD read FExitCode;
end;

implementation

procedure TMyThread.Execute;
var
SI: TStartupInfo;
PI: TProcessInformation;
begin
// Готовим структуру SI
ZeroMemory(@SI, SizeOf(SI));
SI.cb := SizeOf(SI);
// Пытаемся запустить внешнюю программу
if CreateProcess(nil, PChar(FCommandLine), nil, nil, False, 0, nil, PChar(FWorkingDirectory), SI, PI) then
begin
CloseHandle(PI.hThread); // Освобождаем ненужные системные ресурсы
// Ждем завершения с проверкой Terminated 1 раз в секунду.
while not Terminated and (WaitForSingleObject(PI.hProcess, 1000) = WAIT_TIMEOUT) do;
// Или получаем, или формируем код возврата (должна стоять короткая булевская схема)
if Terminated or not GetExitCodeProcess(PI.hProcess, FExitCode) then FExitCode := $FFFFFFFF;
CloseHandle(PI.hProcess) // Освобождаем ненужные системные ресурсы
end
else FExitCode := GetLastError // Запуск не получился, узнаем причину
end;

end.


 
Besa   (2001-09-12 09:56) [6]

> Юрий Зотов
ОГРОМНОЕ СПАСИБО!
Накопал еще коды завершения в книге Архангельского "Делфи 5"
если надо могу перепечатать и вывесить, спрашиваю не потому что лень, а по тому чтоб не делать двойной работы, если это уже сделали другие на этом сайте.
И еще, Юрий, могу ли я ссылаясь на Вас дополнить статью
http://delphi.mastak.ru/articles/winexec/index.html
с Вашим примером, т.к. в данной статье насколько я понял описано на русском языке help дельфи и не сказано о взаимодействии с внешними прогами?


 
Юрий Зотов   (2001-09-12 15:24) [7]

Дополните, если есть желание, дело полезное, почему бы и нет. Только, я думаю, прежде, чем дополнять статью, надо бы получить согласие ее автора, Михаила Подмогова. Или писать свою, самостоятельную статью.

И еще. Если FWorkingDirectory - пустая строка (а это вполне нормально и запросто может быть), то PChar(FWorkingDirectory) даст ошибку. В этом случае в соответствующем параметре CreateProcess надо передавать просто nil и поэтому код метода TMyThread.Execute желательно немного доработать. Например, так:

var
PWorkDir: PChar; // Еще одна локальная переменная в Execute.
...
if FWorkingDirectory = ""
then PWorkDir := nil
else PWorkDir := @FWorkingDirectory[1];

И теперь передаем PWorkDir.

Впрочем, можно и оставить, как есть, просто упомянуть в тексте. "Поимку в пустыне Сахара ручного льва предоставляем читателю в качестве самостоятельного упражнения" (из книги "Физики шутят").


 
Besa   (2001-09-12 17:20) [8]

>Юрий Зотов
Спасибо!
Письмо Михаилу, я уже отправил. Буду ждать ответа.
на свою силенок может не хватить, но попробую.


 
handra   (2001-09-12 19:24) [9]

Еще один вариант запусти и дождаться завершения:

function ExecAndWait(const fname,params: string; nShowCmd: Cardinal): boolean;
var data: TShellExecuteInfo;
begin
Result := false;
data.cbSize := sizeof(data);
data.fMask := SEE_MASK_DOENVSUBST or SEE_MASK_NOCLOSEPROCESS;
data.Wnd := 0;
data.lpVerb := nil;
data.lpFile := PChar(fname);
data.lpParameters := PChar(params);
data.lpDirectory := nil;
data.nShow := nShowCmd;
ShellExecuteEx(@data);
while true do begin
Application.ProcessMessages;
case WaitForSingleObject(data.hProcess,100) of
WAIT_FAILED: Result := false;
WAIT_OBJECT_0: Result := true;
else continue;
end;
break;
end;
end;


 
Delirium   (2001-10-08 18:59) [10]

А слабо просто WinExec(PChar("....."),SW_SHOW) ?


 
vovan1   (2001-11-07 18:15) [11]

Господа, помогите пожалуйста! Попробовал код приведенный Ю.Озеровым, работает, но проблема такая: как запихнуть в архив несколько файлов? Если я делаю цикл, с вызыванием архиватора в отдельном потоке для каждого файла, то у меня в архив попадают только один-или два файла, а надо четыре! Как выйти из данной ситуации? Как тормозуть выполнение следующего процесса, до тех пор, пока предыдущий не отработает? HELP!!!!



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

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

Наверх





Память: 0.49 MB
Время: 0.007 c
1-22058
$Hic0
2001-12-16 11:49
2002.01.08
TTreeView and TListView


7-22421
Shen
2001-08-28 15:05
2002.01.08
Закачка данных через com порт


4-22472
Евгений
2001-10-27 17:03
2002.01.08
Как сделать свой маленький прокси-сервер?


7-22435
sssss
2001-09-23 14:15
2002.01.08
МАСТЕРЫЫЫЫ!!! ВОПРОС ЖИЗНИ И СМЕРТИ !!!!


3-21912
Сергей Н.
2001-12-04 06:23
2002.01.08
Обработка даты из IB в Delphi и обратно





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский