![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно запустить программу, кот удалит которая ее удалит? [D6, Win2k, WinXP]
smu © (2003-12-11 10:33:00)
Ситуация: программа по нажатию на кнопку запускает другую программу, которая удаляет(заменяет ) первую программу?
Пишу:
Procedure TForm1.Button2Click(Sender: TObject);
begin
ShellExecute(0,"open","c:\DPro\Temp\2Project2.exe",nil,nil,SW_SHOW);
fmMain.Close
end;
Правильно ли это? Вроде бы работает, но вдруг будут случаться ситуации, когда первая прога не будет успевать закрываться....
А запущенный файл удалять вроде как нельзя.
Erik (2003-12-11 17:37:00) [1]
Это код ожидания запустившего процеса.
При запуске
CmdParam := FExtractor + " " + IntToStr(ProcessID) + " " + fArhiv;
if CreateProcess(nil, PChar(CmdParam), nil, nil, False,
CREATE_DEFAULT_ERROR_MODE, nil, PChar(ExtractFilePath(ParamStr(0))), SI, PI)
then
begin
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end
............................................
procedure StartApplication;
var
ProcessID: DWORD;
ProcessHandle: THandle;
ExitCode, LastErr: DWord;
PNormal: Boolean;
P: PChar;
ModuleName: string;
Size: Integer;
begin
Size := 0;
if ParamCount() < 2 then
begin
Report("Parameters not found! Count:" + IntToStr(ParamCount()));
Exit;
end;
ProcessID := StrToInt64(ParamStr(1));
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID); //
LastErr := GetLastError;
PNormal := LastErr = 0;
if not PNormal then
Report("Error opening process. Code:" + IntToStr(GetLastError));
//Process allready terninated! 87
if PNormal then
begin
LastErr := WaitForSingleObject(ProcessHandle, INFINITE); // Ждем
GetExitCodeProcess(ProcessHandle, ExitCode);
if LastErr = $FFFFFFFF then
Writeln(OutID, "Error waiting parent process. Code:" +
IntToStr(GetLastError));
if (ExitCode <> 0) and (ExitCode <> 87) then
Writeln(OutID, "Process exit code:" + IntToStr(ExitCode));
SetLength(ModuleName, 256);
P := PChar(ModuleName);
Size := GetModuleFileName(ProcessHandle, P, Length(ModuleName));
SetLength(ModuleName, Size + 1);
Writeln(OutID, "Get =" + IntToStr(Size));
// OemToChar(ModuleName, ModuleName);
(*$WARNINGS OFF*)
P := StrRScan(PChar(ModuleName), "\");
if P <> nil then
StrCopy(PChar(ModuleName), P + 1);
CloseHandle(ProcessHandle);
end;
Digitman (2003-12-11 11:39:00) [2]
> или ID это не хэндл
нет. Id - это не хэндл, это глобально уникальный ид-р процесса в системе, тек.процесс может получить свой собственный ид-р вызовом GetCurrentProcessId
далее, по предложенной схеме, полученный PId передается параметром ком.строки в другое приложение, которое, стартовав и получив переданный ему параметр, получает хэндл процесса вызовом OpenProcess(PId, SYNCRONIZE)
при успешном завершении ф-ции полученный хэндл передается параметром в ф-цию ожидания
при НЕуспешном - это есть факт уже завершившегося на этот момент процесса с указанным PId
smu (2003-12-11 11:35:00) [3]
> kosha80
а то что тип String это ничего?
kosha80 (2003-12-11 11:29:00) [4]
можно попробовать передать Хэндл окна (конечно если оно у тебя главное, его получаешь Form1.handle) в командную строку,
в проге 2 извлекаешь (ParamStr(1)) и циклически проверяешь
while IsWindow(h) do
sleep(100);
DeleteProga1;
Попробуй, может получится...
smu (2003-12-11 11:10:00) [5]
Спасибо разъяснил... что то я про хэндл забыл совсем или ID это не хэндл? А если и хэндл, то как его строкой передать?
Digitman (2003-12-11 11:02:00) [6]
получи в "проге №2" любым удобным способом хэндл процесса "проги №1" (можно даже параметром передать в "прогу №2" Id тек.процесса, т.е. процесса "проги №1") и жди его завершения вызовом любой из ф-ций ожидания (например, WaitForSingleObject)
smu (2003-12-11 10:57:00) [7]
> так пусть "прога №2" ждет факта полного закрытия "проги
> №1" !
а как проверить запущена ли она?
Digitman (2003-12-11 10:48:00) [8]
> Сама себя программа заменить не может ведь
в общем случае - может. но это - из области недок.сист.трюков
> кроме удаления через Dll и Rundll32
чем плох этот подход ? вполне изящный и надежный !
> вдруг будут случаться ситуации, когда первая прога не будет
> успевать закрываться
так пусть "прога №2" ждет факта полного закрытия "проги №1" !
после этого "прога №2" сделает свое черное дело и сама завершится
smu (2003-12-11 10:43:00) [9]
Это нужно для обновления программы (меняю экзешник на более новый). Сама себя программа заменить не может ведь... (кроме удаления через Dll и Rundll32)
REA (2003-12-11 10:38:00) [10]
А можно полюбопытствовать к чему такой извращенный способ самоубийства?