У каждого, конечно, свой способ это делать, но вот как сделал я (обновление не из интернета, а из сетевого диска. Из интернета есть у ErrorSoft, код которого для TFileVersion тут используется
вызов
CheckUpdate(TFileVersion.CreateForFile(ParamStr(0)), cbSilentUpdate.Checked);
сам код
procedure TfrmEnforce.CheckUpdate(Version: TFileVersion; Silent : boolean = true);
var
fn, RemoteFn : string; RemoteVersion : TFileVersion;
begin
fn := ExtractFileName (Application.ExeName);
// fp := ExtractFilePath (Application.ExeName);
RemoteFn := lbeSelfUpdateFolder.Text + '\'+ fn;
if FileExists (RemoteFn) then begin
RemoteVersion := TFileVersion.CreateForFile(RemoteFn);
if Version < RemoteVersion then
if Silent or (not (Silent) and (MessageBox(0, PChar('Update available. Update now?'), PChar(''), MB_ICONQUESTION or MB_YESNO or MB_DEFBUTTON2) = mrYes)) then begin
if FileExists (Application.ExeName + '.old') then DeleteFile (Application.ExeName + '.old');
RenameFile (Application.ExeName, Application.ExeName + '.old');
FileCopy (RemoteFn,Application.ExeName, true);
// fp+'\' + fn, true);
OpenExternalProcess(Application.ExeName);
Halt(0);
end;
end
else begin
MessageDlg('Update file '+RemoteFn+' not exists', mtError, [mbOK], 0);
lbeSelfUpdateFolder.Show;
end;
end;
Используется код выдранный из ErrorSoft Update (спасибо):
+ |
unit FileVersion;
interface
uses System.SysUtils;
type
TFileVersion = record
public
Major: Word;
Minor: Word;
Release: Word;
Build: Word;
//
class operator Equal(L, R: TFileVersion): Boolean;// =
class operator NotEqual(L, R: TFileVersion): Boolean;// <>
class operator GreaterThan(L, R: TFileVersion): Boolean;// >
class operator GreaterThanOrEqual(L, R: TFileVersion): Boolean;// >=
class operator LessThan(L, R: TFileVersion): Boolean;// <
class operator LessThanOrEqual(L, R: TFileVersion): Boolean;// <=
//
constructor Create(VersionStr: string);
{$IFDEF MSWINDOWS}
constructor CreateForFile(FileName: TFileName);
{$ENDIF}
function ToString: string;
end;
{$IFDEF MSWINDOWS}
function GetFileVersion(FileName: string; out Version: TFileVersion): Boolean;
{$ENDIF}
implementation
{$IFDEF MSWINDOWS}
uses
WinApi.Windows;
{$ENDIF}
{$IFDEF MSWINDOWS}
function GetFileVersion(FileName: string; out Version: TFileVersion): Boolean;
var
InfoSize, Wnd: DWORD;
VerBuf: Pointer;
FI: PVSFixedFileInfo;
VerSize: DWORD;
begin
Result := False;
UniqueString(FileName);
InfoSize := GetFileVersionInfoSize(PChar(FileName), Wnd);
if InfoSize <> 0 then
begin
GetMem(VerBuf, InfoSize);
try
if GetFileVersionInfo(PChar(FileName), Wnd, InfoSize, VerBuf) then
if VerQueryValue(VerBuf, '\', Pointer(FI), VerSize) then
begin
Version.Major := HiWord(FI.dwFileVersionMS);
Version.Minor := LoWord(FI.dwFileVersionMS);
Version.Release := HiWord(FI.dwFileVersionLS);
Version.Build := LoWord(FI.dwFileVersionLS);
Result := True;
end;
finally
FreeMem(VerBuf);
end;
end;
end;
{$ENDIF}
{ TFileVersion }
constructor TFileVersion.Create(VersionStr: string);
var
A: TArray<string>;
begin
Major := 0;
Minor := 0;
Release := 0;
Build := 0;
A := VersionStr.Split(['.']);
try
if High(A) >= 0 then
Major := A[0].Trim.ToInteger;
if High(A) >= 1 then
Minor := A[1].Trim.ToInteger;
if High(A) >= 2 then
Release := A[2].Trim.ToInteger;
if High(A) >= 3 then
Build := A[3].Trim.ToInteger;
except
on EConvertError do ;
end;
end;
{$IFDEF MSWINDOWS}
constructor TFileVersion.CreateForFile(FileName: TFileName);
begin
Self := Default(TFileVersion);
GetFileVersion(FileName, Self);
end;
{$ENDIF}
class operator TFileVersion.Equal(L, R: TFileVersion): Boolean;
begin
Result := (L.Major = R.Major) and (L.Minor = R.Minor) and (L.Release = R.Release) and (L.Build = R.Build);
end;
class operator TFileVersion.GreaterThan(L, R: TFileVersion): Boolean;
begin
Result := R < L;
end;
class operator TFileVersion.GreaterThanOrEqual(L, R: TFileVersion): Boolean;
begin
Result := R <= L;
end;
class operator TFileVersion.LessThan(L, R: TFileVersion): Boolean;
begin
Result := False;
// Major
if L.Major > R.Major then Exit(False);
if L.Major < R.Major then Exit(True);
// Minor
if L.Minor > R.Minor then Exit(False);
if L.Minor < R.Minor then Exit(True);
// Release
if L.Release > R.Release then Exit(False);
if L.Release < R.Release then Exit(True);
// Build
if L.Build > R.Build then Exit(False);
if L.Build < R.Build then Exit(True);
end;
class operator TFileVersion.LessThanOrEqual(L, R: TFileVersion): Boolean;
begin
Result := (L < R) or (L = R);
end;
class operator TFileVersion.NotEqual(L, R: TFileVersion): Boolean;
begin
Result := not (L = R);
end;
function TFileVersion.ToString: string;
begin
Result := Format('%d.%d.%d.%d', [Major, Minor, Release, Build]);
end;
end.
|
и
OpenExternalProcess отсюда:
18967332Спасибо JaDi и GunSmoker
Теперь НО.
А оно вот в чём - после завершения работы программы, скаченной с диска, удалить этот файл нельзя никак (можно переименовать, но вот удалить - фиг):
Can not delete the file D:\blablabla\Win32\Debug\Info.lll' Objecy is being open in Unknown (PID: 0) Access is denied