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

Вниз

Обновление программы   Найти похожие ветки 

 
yozhik ©   (2002-11-18 17:15) [0]

Здравствуйте уважаемые мастера!
Вопрос этот поднимался уже несколько раз, но в ответах того, что надо в моем случае я не нашел. если для этой проблемы есть решение, просьба его предложить.
Собственно вопрос: как обновить проге обновить саму себя без перезагрузки компа??
Заранее благодарен.


 
{bas} ©   (2002-11-18 17:37) [1]

Можно реализовать через DLL: Есть .exe - только главное окно или того даже нет, и есть длл - вся остальная прога(подгружается динамически). При выполнении некот. усл. ты выгружаешь длл, переписываешь ее и снова загружаешь.

П.С. но это большой изврат, и мене кажется м. решить твой трабл по другому. Для чего надо, что бы прога сама себя обнавляла.


 
Marcus   (2002-11-18 18:29) [2]

Запустить из программы другую, которая копирует новый файл и запускает его. Главное - проследить, чтобы процесс закрылся до начала копирования.


 
yozhik ©   (2002-11-18 18:44) [3]

Marcus>> а по подробней мона ?
{bas}>> ЮЗЕРЫ ТУПЫЕ, сами переписать не могут, а бегать между 120 чел. мне уже надоело


 
Андрей Прокофьев ©   (2002-11-18 18:47) [4]

а в логин скрипт прописать копирование? (если обновлялось)


 
Marcus   (2002-11-18 19:14) [5]

if NeedForUpdate then begin
WinExec("updater.exe", SW_SHOWNORMAL);
MainForm.Close; // завершаем основной процесс
end;

а в updater.exe такой код:

while (FindWindow("TApplication", ProgramCaption) <> 0) do begin
// ждем пока не закрылся окончательно процесс обновляемого exe
end;

CopyFile(NewFilePath, ExeFilePath, true);
WinExec(ProgramPath, SW_SHOWNORMAL);


 
nick_sniper ©   (2002-11-18 21:58) [6]

Если очень надо, то могу выложить готовый код


 
yozhik ©   (2002-11-19 13:01) [7]

nick_sniper >> буду очень благодарен


 
nick_sniper ©   (2002-11-20 03:01) [8]

Привет землякам.
Код проги Updater.dpr (в двух частях). Не использует Form (из-за этого немножко корявовата), так что размер значительно меньше 300 Кб. После упаковки UPX занимает ~35 Кб.


program Updater;
{$APPTYPE CONSOLE}
uses
windows, shellapi, SysUtils, inifiles;

type
TExecState = (esNormal, esMinimized, esMaximized, esHidden);

var
ini : TIniFile;

function NormalDir(const DirName: string): string;
begin
Result := DirName;
if (Result <> "") and
not (Result[Length(Result)] in [":", "\"]) then
begin
if (Length(Result) = 1) and (UpCase(Result[1]) in ["A".."Z"]) then
Result := Result + ":\"
else Result := Result + "\";
end;
end;

function HasAttr(const FileName: string; Attr: Integer): Boolean;
var
FileAttr: Integer;
begin
FileAttr := FileGetAttr(FileName);
Result := (FileAttr >= 0) and (FileAttr and Attr = Attr);
end;

function DirExists(Name: string): Boolean;
var
Code: Integer;
begin
Code := GetFileAttributes(PChar(Name));
Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;

function GetFileSize(const FileName: string): Longint;
var
SearchRec: TSearchRec;
begin
if FindFirst(ExpandFileName(FileName), faAnyFile, SearchRec) = 0 then
Result := SearchRec.Size
else Result := -1;
FindClose(SearchRec);
end;

procedure ForceDirectories(Dir: string);
begin
if Length(Dir) = 0 then Exit;
if Dir[Length(Dir)] = "\" then
Delete(Dir, Length(Dir), 1);
if (Length(Dir) < 3) or DirExists(Dir) or
(ExtractFilePath(Dir) = Dir) then Exit;
ForceDirectories(ExtractFilePath(Dir));
CreateDir(Dir);
end;

procedure CopyFileEx(const FileName, DestName: string;
OverwriteReadOnly, ShellDialog: Boolean);
var
CopyBuffer: Pointer;
Source, Dest: Integer;
Destination: TFileName;
BytesCopied: Longint;
Attr: Integer;
const
ChunkSize: Longint = 8192;
begin
Destination := DestName;
if HasAttr(Destination, faDirectory) then
Destination := NormalDir(Destination) + ExtractFileName(FileName);
GetMem(CopyBuffer, ChunkSize);
try
Source := FileOpen(FileName, fmShareDenyWrite);
if Source < 0 then
raise EInOutError.CreateFmt("


 
nick_sniper ©   (2002-11-20 03:06) [9]


function DeleteFiles(const FileMask: string): Boolean;
var
SearchRec: TSearchRec;
begin
Result := FindFirst(ExpandFileName(FileMask), faAnyFile, SearchRec) = 0;
try
if Result then
repeat
if (SearchRec.Name[1] <> ".") and
(SearchRec.Attr and faVolumeID <> faVolumeID) and
(SearchRec.Attr and faDirectory <> faDirectory) then
begin
Result := DeleteFile(ExtractFilePath(FileMask) + SearchRec.Name);
if not Result then Break;
end;
until FindNext(SearchRec) <> 0;
finally
FindClose(SearchRec);
end;
end;

function FileExecute(const FileName, Params, StartDir: string;
InitialState: TExecState): THandle;
{$IFDEF WIN32}
begin
Result := ShellExecute(0, nil, PChar(FileName),
PChar(Params), PChar(StartDir), SW_SHOWNORMAL);
end;
{$ELSE}
var
cFileName, cParams, cPath: array [0..80] of Char;
begin
Result := ShellExecute(Application.Handle, nil, StrPCopy(cFileName,
FileName), StrPCopy(cParams, Params), StrPCopy(cPath, StartDir),
ShowCommands[InitialState]);
end;
{$ENDIF}

function CopyFiles :boolean;
var
i, j : Integer;
DirFrom, DirTo, Dir, File1 : string;
begin
Result := False;
j := ini.ReadInteger("Files","Files",0);
DirFrom := ini.ReadString("Application", "PathFrom", "" );
DirTo := ini.ReadString("Application", "PathTo", "..\" );
for i := 1 to j do begin
Dir := ini.ReadString("Files", "Dir"+IntToStr(i), "" );
Dir := trim(Dir);
if (Length(Dir) > 0) and (Dir[Length(Dir)] <> "\") then
Dir := Dir + "\";
if not DirExists(DirTo+Dir) then
CreateDir(DirTo+Dir);
File1 := ini.ReadString("Files", "File"+IntToStr(i), "" );
if trim(File1) <> "" then begin
if FileExists(DirFrom+File1) then
if FileExists(DirTo+Dir+File1) then
DeleteFiles(DirTo+Dir+File1);
CopyFile(DirFrom+File1,DirTo+Dir+File1);
end;
end;
if j > 0 then
Result := True;
end;

procedure Delay(MSecs: Longint);
var
FirstTickCount, Now: Longint;
begin
FirstTickCount := GetTickCount;
repeat
{ allowing access to other controls, etc. }
Now := GetTickCount;
until (Now - FirstTickCount >= MSecs) or (Now < FirstTickCount);
end;

begin
Delay(2000);
ini := TIniFile.Create(".\Update.ini");
try
if CopyFiles then begin
if ini.ReadString("Main","AfterUpdate","") <> "" then begin
if FileExecute(ini.ReadString("Main","AfterUpdate",""),"","",esNormal) > 32 then
ini.WriteInteger("Application","Updated",1);
end else
ini.WriteInteger("Application","Updated",1);
FileExecute(ini.ReadString("Application","PathTo","")+ini.ReadString("Main","Run",""),"",ini.ReadString("Application","PathTo",""),esNormal)
end;
finally
ini.Free;
end; {try}
end.


 
nick_sniper ©   (2002-11-20 03:09) [10]

Формат Update.ini файла, который передается вместе с Updater.exe:


; Секцію заповняє програміст
[Main]

; Версія нового файлу, повинна бути більша ніж у того, що у користувача
Version=1.0.0.38

; Ім"я файлу, який виконує оновлення
Updater=Updater.exe

; Програма яка запускається після оновлення з поточного каталогу
AfterUpdate=

; Програма, яка буде виконана після оновлення з каталогу, куди переписане оновлення
Run=BKReport.exe


; Секція файлів для копіювання
[Files]

;Кількість файлів
Files=1

; Файл
File1=BKReport.exe
; в директорію
Dir1=

; Файл
File2=
; в директорію
Dir2=


; Секцію заповняє програма автоматично
[Application]

; 0 - якщо потрібно виконати оновлення, 1 - оновлення виконано
Updated=0

; директорія куди потрібно переписати файли
PathTo=D:\MyDocuments\Commercial\BKReport100\

; директорія, звідки беруться файли
PathFrom=D:\MyDocuments\Commercial\BKReport100\Update\




 
nick_sniper ©   (2002-11-20 03:19) [11]

В свою программу встраиваешь следующий код для проверки обновлений:


const
DirUpdate = "Update";
FileUpdate = "Update.ini";

function CheckUpdates : Boolean;
var
ini : TIniFile;
ver : string;
begin
Result := False;
if not DirExists(AppPath+DirUpdate) then
CreateDir(AppPath+DirUpdate);
if FileExists(AppPath+DirUpdate+"\"+FileUpdate) then begin
// есть апдейт
ini := TIniFile.Create(AppPath+DirUpdate+"\"+FileUpdate);
try
ver := ini.ReadString("Main","Version","0");
if (ver <= cVersion) or (ini.ReadInteger("Application","Updated",-1)=1) then begin
DeleteFiles(AppPath+DirUpdate+"\*.*");
Exit;
end;
MessageDlg("Знайдено оновлення v."+ver+#13+#10+"Зараз спробую його завантажити...", mtInformation, [mbOK], 0);
ini.WriteInteger("Application","Updated",0);
ini.WriteString("Application","PathTo",AppPath);
ini.WriteString("Application","PathFrom",AppPath+DirUpdate+"\");
if FileExecute(ini.ReadString("Main","Updater","Updater.exe"),"",AppPath+DirUpdate,esNormal) <= 32 then begin
MessageDlg("Оновлення не вдалося завантажити."+#13+#10+"Продовжую роботу програми.", mtWarning, [mbOK], 0);
//DeleteFiles(AppPath+DirUpdate+"\*.*");
end else
Result := true;
finally
ini.Free;
end; {try}
end;
end;


И где-то в файле проекта XXX.dpr ставишь:


if CheckUpdates then begin
Application.Terminate;
Exit;
end;


Извини, если что не так. Код вырезан из рабочей программы, так что немножко получилось коряво. Кажется к проекту потребуется подключить RxLib (точно не помню)

Если что - пиши ;-)



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

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

Наверх




Память: 0.51 MB
Время: 0.022 c
3-4256
Tumcoat
2002-11-14 04:49
2002.12.02
Поблемы с запросом в элементе Query


3-4237
Akhmadey
2002-11-12 20:42
2002.12.02
Проблема с DBChart


1-4455
Separator
2002-11-20 11:21
2002.12.02
Бипер на все системах


3-4251
bugs
2002-11-14 15:44
2002.12.02
Таблица DBF.


1-4334
Slaviq
2002-11-19 20:38
2002.12.02
TTreeView