Форум: "Основная";
Текущий архив: 2002.12.02;
Скачать: [xml.tar.bz2];
ВнизОбновление программы Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c