Простой способ автообновления (AUTOUPDATE) ... и всё бы хорошо ... НО

Victor Cookin
Дата: 09.08.2019 18:45:28
У каждого, конечно, свой способ это делать, но вот как сделал я (обновление не из интернета, а из сетевого диска. Из интернета есть у 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
Мимопроходящий
Дата: 09.08.2019 18:48:01

09.08.2019 18:45, Victor Cookin пишет:
> Can not delete the file

какая ОСь и какие антивирусы?

Posted via ActualForum NNTP Server 1.5

Victor Cookin
Дата: 09.08.2019 18:49:16
Мимопроходящий,

Windows 7 Pro, McAfee
Victor Cookin
Дата: 09.08.2019 18:51:04
Мимопроходящий,

С этим сетевым диском вообще чудеса - если пытаешься с него стартовать программу, то DOA не находит TNSNAMES. Хотя казалось бы -какая разница откуда прога загружена.
Мимопроходящий
Дата: 09.08.2019 18:51:07

09.08.2019 18:49, Victor Cookin пишет:
> Windows 7 Pro, McAfee

проверь на "чистой" железяке, без антивируса.

Posted via ActualForum NNTP Server 1.5

Victor Cookin
Дата: 09.08.2019 19:02:09
При этом если загрузка новой версии с локального диска - всё нормально удаляется
Гаджимурадов Рустам
Дата: 09.08.2019 19:11:44
Victor Cookin> удалить этот файл нельзя никак
Victor Cookin> Can not delete the file
Victor Cookin> Objecy is being open in Unknown (PID: 0) Access is denied

А что показывает Find Handler (кто его удерживает) ?

Posted via ActualForum NNTP Server 1.5

X-Cite
Дата: 09.08.2019 19:22:12
Можно поставить anvir task manager и посмотреть кто удерживает
Victor Cookin
Дата: 09.08.2019 19:28:25
Гаджимурадов Рустам,

Файл прекрасно открывается, но сохраняться отказывается. Говорит:
Can't open file: The requested operation cannot be performed on a file with a user-mapped section open
Victor Cookin
Дата: 09.08.2019 19:29:19
X-Cite,

anvir task manage не даст поставить антивирус, я уверен