Jump to content
Skrim

Update an application automatically

Recommended Posts

What do you use to make an application, made with Delphi, check for updates and let the user choose to update or not?

 

Links appreciated 🙂

 

I have a component set for this, but it's too hard to use (at least for me) and I'm giving it up.

Share this post


Link to post

TMS has a commercial package, you read more about it at https://www.tmssoftware.com/site/wupdate.asp

 

I wrote my own, open source version which I am using in my main application for a while now and seems to do it's job properly. I attempted to build it up to be as versatile as possible but it's probably still a toddler compared with TMS when it comes to features, though.

 

There's an example code on how to create an update file and how to update your application here:

 

  • Like 1

Share this post


Link to post

Five stars for the TMS version. This has worked perfectly for me for a number of years!

Share this post


Link to post

I got code that checks for a new version, downloads it to a temp file.

Renames the running file, and renames the temp file to the running name,

and then uses this code to relaunch.  Works for .exe files and services.

Has worked well for a decade.

 

Share this post


Link to post
4 hours ago, Lars Fosdal said:

Renames the running file

Are you sure that is what it does? As far as I know only DLLs can be renamed while in use, but not EXEs (*1).

 

147236908_2023-02-1017_04_21-FileInUse.png.c5e3771ae2943a87a22afbbb83acce13.png

 

(*1: Unless the EXE is located on a Samba-Sever share but then it can only renamed directly on the Unix/Linux box and if you do that it will come back to bite you.)

Edited by dummzeuch

Share this post


Link to post
35 minutes ago, dummzeuch said:

As far as I know only DLLs can be renamed while in use, but not EXEs (*1).

No, my updater is using the exact same mechanism and is working perfectly on every type of file (even system installed fonts).

Share this post


Link to post

@aehimself I am impressed by your updater and other useful things you collected, maybe you like to upgrade the unit OSVersion.pas

type
  TTrueVersion = packed record
    Major,
    Minor,
    Build: DWORD;
  end;
 
procedure RtlGetNtVersionNumbers(out MajorVersion, MinorVersion, BuildNumber: DWORD); stdcall; external 'Ntdll.dll';
function GetTrueVersion: TTrueVersion;
var
  vMaj,
  vMin,
  vBuild: DWORD;
begin
  RtlGetNtVersionNumbers(vMaj, vMin, vBuild);
  Result.Major := vMaj;
  Result.Minor := vMin;
  Result.Build := Lo(vBuild);
end;
 
procedure TForm1.FormCreate(Sender: TObject);
var
  ver: TTrueVersion;
begin
  ver := GetTrueVersion;
  Label1.Caption := Format('Running Windows %d.%d Build: %d', [ver.Major, ver.Minor, ver.Build]);
end;

That's the most accurate way to determine a Windows version that I do know.

Share this post


Link to post

Not having to include the manifest file sounds promising, but this method only returns the OS version and nothing else.

I might look into it in the future if I'll need that unit again.

Share this post


Link to post
On 2/10/2023 at 5:00 PM, dummzeuch said:

Are you sure that is what it does? As far as I know only DLLs can be renamed while in use, but not EXEs (*1).

Yes. I wrote it, and it has been used in production for nearly a decade. 

Share this post


Link to post
1 hour ago, Lars Fosdal said:

Yes. I wrote it, and it has been used in production for nearly a decade. 

Hm, neither Explorer nor the rename command on the commandline can rename an executable that is currently running, so I have so far assumed that's not possible.

Share this post


Link to post
4 hours ago, dummzeuch said:

Hm, neither Explorer nor the rename command on the commandline can rename an executable that is currently running, so I have so far assumed that's not possible.

My Updater process does the same thing - rename the original (running) instance to app.exe.old, copy (or download) the new instance as app.exe. The original instance continues running - as app.exe.old - until terminated. When the update process is completed and the original instance is terminated, it is only at this time that the original instance, app.exe.old, can be deleted, so I run a clean-up routine on the next program launch to remove any .old files.

 

I seem to recall that this operation wasn't so reliable on XP, but it's some time since I tested it on that OS. I can confirm it works fine on 7 and above.

Share this post


Link to post

That's really odd. I just tried it because I couldn't believe it:

VCL-Application with a form and a button b_Rename and the following code:

procedure TRenameExeTest.b_RenameClick(Sender: TObject);
begin
  RenameFile(Application.ExeName, Application.ExeName + '.old');
end;

Works as expected or rather as not expected by me.

 

Now I wonder why the Explorer and the Rename command cannot do this.

 

Interestingly, after the program has renamed its own executable, it's possible to rename it back using the Explorer.

 

And even more strange: This program can be renamed with the Explorer while its running. The one I tried first (last post with the screenshot) could not. I wonder what causes this. Maybe it's DxGettext that keeps the file open because it accesses the linked in translations? Or JclDebug accessing the jdbg information in the file?

Share this post


Link to post

In the past we always did our own auto updating using a similar approach as presented here (rename exe, download new version, then restart). This works as long as the the application is installed inside the user profile, not when it gets installed in 'Program files'.

Nowadays we let Windows handle this using an MSIX installer accompanied by an .appinstaller file (you can configure auto update behavior from the appinstaller file). In my experience, using the .appinstaller gives a much better user experience than any other method.

Share this post


Link to post
On 2/11/2023 at 10:24 PM, dummzeuch said:

Hm, neither Explorer nor the rename command on the commandline can rename an executable that is currently running, so I have so far assumed that's not possible.

We've not experienced any significant problems with it, but then again, our apps run in a controlled environment.

Share this post


Link to post
On 2/12/2023 at 2:32 PM, Keesver said:

Nowadays we let Windows handle this using an MSIX installer accompanied by an .appinstaller file

But this doesn't work for Windows 7 from what I understand.

 

On 2/12/2023 at 2:32 PM, Keesver said:

This works as long as the the application is installed inside the user profile, not when it gets installed in 'Program files'. 

We used Chrome approach for this and avoided elevation to write in 'Program files'. Elevation is necessary only first time at installation when we create a task in scheduler on the SYSTEM account.

Actually two tasks: one with a day trigger and one with a trigger that can be started from our app at demand.

Edited by Cristian Peța
  • Like 1

Share this post


Link to post
41 minutes ago, Cristian Peța said:

But this doesn't work for Windows 7 from what I understand.

Is that still a valid deterrent?

 

Share this post


Link to post
54 minutes ago, Sherlock said:

Is that still a valid deterrent?

 

I like W7 much better than W10. For me, W10 just don't have enough sweeties to upgrade. Moreover, in some aspects it is worse

Share this post


Link to post

Support for appinstaller is available since W10 (see Troubleshoot installation issues with the App Installer file - MSIX | Microsoft Learn). We have had issues in the past with the auto update feature (users had to restart their computer before the auto update would work) but that has been fixed by MS. 

 

47 minutes ago, Cristian Peța said:

More than 10% from 12500 installations in last year are Windows 7 and 8

We still support both update processes side by side having two separate installers. If you need to support W7 and W8 I think there is no way around this.

Share this post


Link to post

@Keesver I used appinstaller and updates are working well (installing and updates without admin elevation) but I didn't managed to show transparent icon on taskbar.

I posted in other thread what I was doing if you have some suggestions:

 

Edited by Cristian Peța

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×