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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.01 c
1-93993
Edik86
2004-02-16 19:35
2004.02.29
StringList


3-93776
-=[SDA]=-
2004-02-04 07:28
2004.02.29
Как пронумеровать записи???


3-93754
Fom
2004-02-04 16:45
2004.02.29
Как посчитать количество страниц в QReport?


6-94071
Alex-drob
2003-12-22 13:55
2004.02.29
Pop3


6-94078
Alex-11111
2003-12-19 13:50
2004.02.29
Получение почты





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