Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.29;
Скачать: CL | DM;

Вниз

Как правильно запустить программу, кот удалит которая ее удалит?   Найти похожие ветки 

 
smu ©   (2003-12-11 10:33) [0]

Ситуация: программа по нажатию на кнопку запускает другую программу, которая удаляет(заменяет ) первую программу?
Пишу:
Procedure TForm1.Button2Click(Sender: TObject);
begin
ShellExecute(0,"open","c:\DPro\Temp\2Project2.exe",nil,nil,SW_SHOW);
fmMain.Close
end;

Правильно ли это? Вроде бы работает, но вдруг будут случаться ситуации, когда первая прога не будет успевать закрываться....
А запущенный файл удалять вроде как нельзя.


 
REA ©   (2003-12-11 10:38) [1]

А можно полюбопытствовать к чему такой извращенный способ самоубийства?


 
smu ©   (2003-12-11 10:43) [2]

Это нужно для обновления программы (меняю экзешник на более новый). Сама себя программа заменить не может ведь... (кроме удаления через Dll и Rundll32)


 
Digitman ©   (2003-12-11 10:48) [3]


> Сама себя программа заменить не может ведь


в общем случае - может. но это - из области недок.сист.трюков


> кроме удаления через Dll и Rundll32


чем плох этот подход ? вполне изящный и надежный !


> вдруг будут случаться ситуации, когда первая прога не будет
> успевать закрываться


так пусть "прога №2" ждет факта полного закрытия "проги №1" !
после этого "прога №2" сделает свое черное дело и сама завершится


 
smu ©   (2003-12-11 10:57) [4]


> так пусть "прога №2" ждет факта полного закрытия "проги
> №1" !

а как проверить запущена ли она?


 
Digitman ©   (2003-12-11 11:02) [5]

получи в "проге №2" любым удобным способом хэндл процесса "проги №1" (можно даже параметром передать в "прогу №2" Id тек.процесса, т.е. процесса "проги №1") и жди его завершения вызовом любой из ф-ций ожидания (например, WaitForSingleObject)


 
smu ©   (2003-12-11 11:10) [6]

Спасибо разъяснил... что то я про хэндл забыл совсем или ID это не хэндл? А если и хэндл, то как его строкой передать?


 
kosha80   (2003-12-11 11:29) [7]

можно попробовать передать Хэндл окна (конечно если оно у тебя главное, его получаешь Form1.handle) в командную строку,
в проге 2 извлекаешь (ParamStr(1)) и циклически проверяешь

while IsWindow(h) do
sleep(100);
DeleteProga1;

Попробуй, может получится...


 
smu ©   (2003-12-11 11:35) [8]


> kosha80

а то что тип String это ничего?


 
Digitman ©   (2003-12-11 11:39) [9]


> или ID это не хэндл


нет. Id - это не хэндл, это глобально уникальный ид-р процесса в системе, тек.процесс может получить свой собственный ид-р вызовом GetCurrentProcessId

далее, по предложенной схеме, полученный PId передается параметром ком.строки в другое приложение, которое, стартовав и получив переданный ему параметр, получает хэндл процесса вызовом OpenProcess(PId, SYNCRONIZE)

при успешном завершении ф-ции полученный хэндл передается параметром в ф-цию ожидания

при НЕуспешном - это есть факт уже завершившегося на этот момент процесса с указанным PId


 
Erik ©   (2003-12-11 17:37) [10]

Это код ожидания запустившего процеса.
При запуске
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;



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

Текущий архив: 2004.02.29;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.027 c
14-94099
ИМХО
2004-02-09 20:38
2004.02.29
Динамо Киев: в чем причина популярности команды в Советское время


6-94049
dolphin1
2003-12-24 13:01
2004.02.29
ICQ


3-93798
NoName
2004-02-03 16:08
2004.02.29
Проблема c DBEdit


1-93899
Jeen
2004-02-14 22:44
2004.02.29
Доступ к списку команд, вводившихся в


3-93778
John S.
2004-02-04 08:01
2004.02.29
AdoCommand