Постоянно возникают проблемы с работой апдейтера. Хотелось бы разобраться что не так. На клиент посылается команда на обновление. Клиент начинает скачивать обновление. После скачивания обновления клиент закрывается и запускает апдейтер. Апдейтер в своё время распаковывает архив, потом удаляет его и запускает клиент.
Вот как это выглядет в коде
Работа с архивом (*.RAR)
Код:
procedure LOG(S : string);
begin
Form1.Memo1.Lines.Add(S);
end;
type
TRAROpenArchiveData = record
ArcName : PChar;
OpenMode : cardinal;
OpenResult : cardinal;
CmtBuf : PChar;
CmtBufSize : cardinal;
CmtSize : cardinal;
CmtState : cardinal;
end;
TRARHeaderData = record
ArcName : array[0..259] of char;
FileName : array[0..259] of char;
Flags : cardinal;
PackSize : cardinal;
UnpSize : cardinal;
HostOS : cardinal;
FileCRC : cardinal;
FileTime : cardinal;
UnpVer : cardinal;
Method : cardinal;
FileAttr : cardinal;
CmtBuf : PChar;
CmtBufSize : cardinal;
CmtSize : cardinal;
CmtState : cardinal;
end;
TUnRarCallBack = function(msg: Cardinal; UserData, P1, P2: integer): integer; stdcall;
function RAROpenArchive(var ArchiveData : TRAROpenArchiveData): THandle; stdcall;
external 'unrar.dll' name 'RAROpenArchive';
function RARCloseArchive(hArcData : THandle): Integer; stdcall;
external 'unrar.dll' name 'RARCloseArchive';
function RARReadHeader(hArcData : THandle; out HeaderData : TRARHeaderData): Integer; stdcall;
external 'unrar.dll' name 'RARReadHeader';
function RARProcessFile(hArcData : THandle; Operation : Integer; DestPath : pchar;
DestName : pchar = nil): Integer; stdcall;
external 'unrar.dll' name 'RARProcessFile';
procedure RARSetCallback (hArcData: THandle; Callback: TUnRarCallback; UserData: longint); stdcall;
external 'unrar.dll' name 'RARSetCallback';
const
ERAR_END_ARCHIVE = 10;
RAR_OM_EXTRACT = 1;
RAR_EXTRACT = 2;
RAR_SUCCESS = 0;
UCM_PROCESSDATA = 1;
var
RARHeaderData : TRARHeaderData;
ArcStruct: TRAROpenArchiveData;
CmtBuffer : array[0..1023] of char;
function UnRarCallBack(msg: Cardinal; UserData, P1, P2: integer): integer; stdcall;
begin
Result := 0;
if msg = UCM_PROCESSDATA then LOG('Распаковал ' + IntToStr(P2) + ' байт');
end;
function OpenRARArchive(FileName : string) : THandle;
begin
ZeroMemory(@ArcStruct, sizeof(ArcStruct));
ArcStruct.OpenMode := RAR_OM_EXTRACT;
ArcStruct.ArcName := pchar(FileName);
ArcStruct.CmtBuf := CmtBuffer;
ArcStruct.CmtBufSize := sizeof(CmtBuffer);
Result := RAROpenArchive(ArcStruct);
end;
procedure UnRarFile(RarFileName : string; Directory : string = '');
var
hRAR : THandle;
hReadHeader : integer;
hProcessHeader : integer;
begin
UniqueString(RarFileName);
RarFileName := ExpandFileName(RarFileName);
UniqueString(Directory);
LOG('Распаковываю архив "' + RarFileName + '" в папку "' + Directory + '"...');
CharToOem(pchar(Directory), pchar(Directory));
hRAR := OpenRARArchive(RarFileName);
RARSetCallback(hRar, UnRarCallBack, 0);
hReadHeader := 0;
hProcessHeader := 0;
REPEAT
hReadHeader := RARReadHeader(hRar, RARHeaderData);
if hReadHeader = ERAR_END_ARCHIVE
then Break;
OemToChar(RARHeaderData.FileName, RARHeaderData.FileName);
LOG('Распаковываю файл "' + string(RARHeaderData.FileName) +
'"... ' + IntToStr(RARHeaderData.UnpSize) + ' байт.');
if hReadHeader = RAR_SUCCESS then
hProcessHeader := RARProcessFile(hRar, RAR_EXTRACT, PChar(Directory), nil);
UNTIL (hProcessHeader <> RAR_SUCCESS);
LOG('Всё распаковано, закрываю архив.');
RARCloseArchive(hRAR)
end;
Если архив не найден, то закрываем приложение, если же он найден закрывает клиент и ждём 10 секунд (для подстраховки, для полного закрытия)
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
if not FileExists(ExtractFilePath(Application.EXEName)+'update.rar') then begin
Application.Terminate;
Exit;
end else
Timer1.Enabled:=True;
end;
Начинаем само обновление
Код:
Memo1.Lines.Clear;
UnRarFile(ExtractFilePath(Application.EXEName)+'update.rar');
DeleteFile(ExtractFilePath(Application.EXEName)+'update.rar');
ShellExecute(0, 'open', pChar(ExtractFilePath(Application.ExeName)+'CSS.exe'), 0, 0, SW_HIDE);
Timer1.Enabled:=False;
Application.Terminate;
Чаще всего после окончания обновления клиент не запускается. И ждать 10 секунд тоже как-то стрёмно. Как можно сделать нормально (старт обновления после закрытия клиента и нормальный запуск после окончания обновления).