Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-4409
Сутковой Вадим
2002-11-17 17:04
2002.12.02
Как правильно перетащить форму не за заголовок?


1-4301
SiaCD
2002-11-19 19:47
2002.12.02
Дата создания файла...как поменять?


3-4228
akzhan
2002-11-13 19:52
2002.12.02
Приглашаю почитать драфт моего опуса.


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


8-4520
vasya_dvc
2002-08-07 22:45
2002.12.02
Почему Photoshop не понимает?





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