TWebUpdate with VirtualStore

Hi,

I use TWebUpdate, who need to restart a Delphi exe.
This exe, who is located in C:\Program Files (x86)\MySoftware\Sofware.exe, need to read a file located in VirtualStore\Program Files (x86)<span style="line-height: 19.6000003814697px;">MySoftware</span>
I use the FileExists command before read the file.

If I run Software.exe directly (by click on the exe), i can find the file on VirtualStore
If it's wusetup.exe who run Software.exe, i can't find the file.

Any explanation?

Thanks

Can it be it is because the Windows user account running the app directly versus the one running the app after restart (i.e. Admin) is different?
Also, does your app have any dependency on the current directory where the app is running?
If so, possibly you could resolve this by SetCurrentDir(ExtractFilePath(Application.EXEName));

I try force CurrentDir before restart, and before call my FileExists, but it doesn't work.


Yes, probably it is because of Windows user. But i can't specify user Admin to wusetup.exe.

For example, i try something simple, in a Delphi program:

if i call:
ShellExecute(0,'open',pchar('C:\Program Files (x86)<span style="line-height: 19.6000003814697px;">MySoftware\Software.exe'),nil,nil,SW_SHOW);
the command FileExists works (Software.exe can read VirtualStore)

if i call this:
commandline:='5084 X "C:\Program Files (x86)\MySoftware\Software.exe" " " "C:\Users\nasch\AppData\Local\Temp"';
ShellExecute(0,'open',pchar('C:\Users\nasch\AppData\Local\Temp' + 'wusetup.exe'),pchar(commandline),nil,SW_SHOW);
FileExists doesn't work.

The problem is that I don't know what exactly happen in wusetup.exe

wusetup.exe is compiled with a manifest to elevate to admin privs (via UAC / because it needs permission to access \Program files for updating the application) , so, it would appear that as admin, FileExists() doesn't see the same files as a regular Windows user account does? Sadly, as long as WebUpdate is used to replace running EXEs from \Program Files UAC is needed. If you app is not stored under \Program Files, you could compile TWebUpdate in non-UAC mode and then it will run a version of wusetup.exe that doesn't elevate to admin. So, if your app is not under \Program files, it could be worth trying that.

Hello,

May I not explain correctly.
My problem is when I try to run a program from C:\Program Files (x86)

This is a quick code for show you (I don't know how to attach a .rar at this post):

unit Test;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,IniFiles, Vcl.StdCtrls, ShellApi, WUpdate;

type
  TForm1 = class(TForm)
    TestFile: TButton;
    CreateFile: TButton;
    RestartOK: TButton;
    RestartKO: TButton;
    procedure CreateFileClick(Sender: TObject);
    procedure TestFileClick(Sender: TObject);
    procedure RestartOKClick(Sender: TObject);
    procedure RestartKOClick(Sender: TObject);
  private
    { Déclarations privées }
    function WinTempDir: string;
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function AddBackslash(const s: string): string;
begin
  if (Length(s) >= 1) and (s[Length(s)]<>'') then
    Result := s + ''
  else
    Result := s;
end;

procedure TForm1.TestFileClick(Sender: TObject);
begin
  if FileExists(ExtractFilePath(Application.ExeName)+'test.ini') then
    ShowMessage('FileExists:'+ExtractFilePath(Application.ExeName)+'test.ini')
  else
    ShowMessage('FILE NOT FOUND');
end;

procedure TForm1.CreateFileClick(Sender: TObject);
var Fic:TMemIniFile;
begin
  Fic:=TMemIniFile.Create(ExtractFilePath(Application.ExeName)+'test.ini');
  try
    Fic.WriteDate('MiseAJour','DateMAJ',Date);
  finally
    Fic.UpdateFile;
    Fic.Free;
  end;
end;

procedure TForm1.RestartOKClick(Sender: TObject);
begin
  ShellExecute(0,'open',pchar(Application.ExeName),nil,nil,SW_SHOW);
end;

function TForm1.WinTempDir: string;
var
  buf:string;
  i: integer;
begin
  SetLength(buf, MAX_PATH);
  i := GetTempPath(Length(buf), PChar(buf));
  SetLength(buf, i);

  Result := AddBackslash(buf);
end;

procedure TForm1.RestartKOClick(Sender: TObject);
var commandline:String;

begin
  commandline:='5084 X "'+Application.ExeName+'" " " "'+WinTempDir+'"';
  ShellExecute(0,'open',pchar(ExtractFilePath(Application.ExeName) + 'wusetup.exe'),pchar(commandline),nil,SW_SHOW);
end;

end.

I use the wusetup.exe created by TWebUpdate.

Try this:

Copy PTest.exe and wusetup.exe in C:\Program Files (x86)

Run PTest.exe

Clic on CreateFileClick  => it create a file on C:\Users&lt;User>\AppData\Local\VirtualStore\Program Files (x86)

clic on TestFileClick => command FileExists ok (found the file on VirtualStore, even the path is C:\Program Files (x86)\test.ini)

Clic on RestartOKClick => open a new PTest.exe
    And clic on TestFileClick => OK

Clic on RestartKOClick => open a new PTest.exe
    And clic on TestFileClick => NOT OK

oh ok, I understand: if I run PTest.exe as administrator, I can not find the file.


But wusetup.exe force running as admin.

How can I do, if I want to keep my exe on Program Files?

Hi,

I run WUpdate without UAC, and then, it use wurepl.exe instead of wusetup.exe
It seems to work, even I need to restart an exe located on C:\Program Files.

Thanks a lot

Sorry, to replace an EXE file under c:\Program Files , it is required to use UAC to elevate to admin privs as normal user privs cannot write to c:\Program Files.

Normally, TWebUpdate executes the updater and after this, restarts the new EXE itself (with which there are no known issues using UAC), so it is not clear why you need to start this EXE yourself.

oh, sorry for my bad explanation and my missunderstanding.


I understand that TWebUpdate need to elevate to admin for write in C:\Program Files, no problem.

I don't want to use the wurepl.exe in my program. I just try to extract the part of TWebUpdate code who make the restart, and put in in a simple project, for trying to understand what happen.

OK, from the beginning:
 case:
- MySoftware.EXE located in C:\Program Files, not with admin privs
- on first running, my EXE write a file, but with no admin privs, it write on VirtualStore
- when EXE running again (still not admin privs), it read the file on VirtualStore => no problem

2° case:
- MySoftware.EXE located in C:\Program Files, with admin privs
- on first running, my EXE write a file on C:\Program Files (no need VirtualStore now)
- when EXE running again (still with admin privs), it read the file on C:\Program Files => no problem

My problem:
MySoftware.EXE located in C:\Program Files, not with admin privs
- It use TWebUpdate for update my EXE and restart it
- if I compile TWebUpdate with USEUAC:
- can update exe
- restart EXE with admin privs
- my EXE try to find the file in C:\Program Files, whereas it located on VirtualStore => problem
- if I compile TWebUpdate without USEUAC:
- can not update exe => problem
- restart EXE with not admin privs
- my EXE can find the file in VirtualStore

I hope I explain it correctly ;-)
Thanks