Cleanly update older versions of my application installed using NSIS

780 views
Skip to first unread message

Ahnaf Mahmud

unread,
Jun 4, 2022, 3:28:35 PM6/4/22
to innosetup
When I first created my application, I used NSIS to create the installer for distribution. However, in the upcoming update of my application, version 1.3 I have made some changes to the application itself and as part of the changes I have switched to using Inno Setup. 

I would like to seamlessly update the installations of versions older than 1.3. One way I can check if the older version is installed is by checking if the uninstall.exe file is present (the uninstallation executable name for Inno is different so that's why I was thinking of this), and then do a silent uninstall before proceeding with the new installation. But I only found documentation for running programs after the installation is complete. I need it to be done before.

I don't need any UAC  privileges , it can be uninstalled without UAC, since this is for my Win32 listing for Microsoft Store I need the updates to be done seamlessly. I also have my application on GitHub releases but I have instead put a notice on the GH Releases version to uninstall the old version.

Also, I would like to know if I should keep the app ID the same for future updates to my application.

Would appreciate if anyone could help with this.

Jernej Simončič

unread,
Jun 4, 2022, 5:22:21 PM6/4/22
to Ahnaf Mahmud on [innosetup]

On Saturday, June 4, 2022, 21:28:35, Ahnaf Mahmud wrote:


I would like to seamlessly update the installations of versions older than 1.3. One way I can check if the older version is installed is by checking if the uninstall.exe file is present (the uninstallation executable name for Inno is different so that's why I was thinking of this), and then do a silent uninstall before proceeding with the new installation. But I only found documentation for running programs after the installation is complete. I need it to be done before.

There are two ways you can do this:

- run the old uninstaller silently from the CurStepChanged(ssInstall) event function in [Code]

- use [InstallDelete] and [Registry] sections to delete the old uninstall info during install (use deletekey and/or deletevalue flags in [Registry])

 

The second one is a bit more manual work, but will let your install run faster. You have to remove the old uninstall info from Registry, because the uninstall key that Inno creates always has _is1 appended, so you will not be able to make it identical to the uninstall key created by NSIS.

 

-- 
< Jernej Simončič ><><><><>< https://eternallybored.org/ >


A good plan today is better than a perfect plan tomorrow.
       -- Patton's Law

ip18

unread,
Jun 5, 2022, 5:16:01 PM6/5/22
to innosetup
I managed to get somewhere with the implementation, but I still have two issues:

1. I want to uninstall silently using uninstall.exe /S. But not sure how to do that in the code.
2. The installer doesn't wait until the uninstaller is finished. I did a workaround by making the installer wait for 10 seconds before continuing but I don't think that's ideal.

Do you know how I can do these two things?

Here is my code currently:

procedure CurStepChanged(CurStep: TSetupStep);
var
  ErrorCode: integer;
begin
  if CurStep = ssInstall then
  begin
    if (FileExists(ExpandConstant('{app}\uninstall.exe'))) then
    begin
      Exec(ExpandConstant('{app}\uninstall.exe'), '', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
      Sleep(10000);
    end;
  end;
end;


Jernej Simončič

unread,
Jun 6, 2022, 7:40:03 AM6/6/22
to ip18 on [innosetup]

On Sunday, June 5, 2022, 23:16:01, ip18 wrote:

 

1. I want to uninstall silently using uninstall.exe /S. But not sure how to do that in the code.

Exec(ExpandConstant('{app}\uninstall.exe'), '/S', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode); 

 

2. The installer doesn't wait until the uninstaller is finished. I did a workaround by making the installer wait for 10 seconds before continuing but I don't think that's ideal.

This depends on how the NSIS uninstaller works – nearly all uninstallers copy themselves to %TEMP%, and then re-run from there; if the original .exe exits immediately (instead of waiting for a signal from the child process), there's no easy way to wait for the uninstaller to finish.

 

I suggest you don't run the old uninstaller, and instead delete it with [InstallDelete], and remove the old uninstall registry info with [Registry] instead, this way you'll avoid the whole problem.

-- 
< Jernej Simončič ><><><><>< https://eternallybored.org/ >


Inside every large problem is a small problem struggling to get out.
       -- Hoare's Law of Larger Problems

Bill Stewart

unread,
Jun 6, 2022, 11:42:45 AM6/6/22
to innosetup
On Saturday, June 4, 2022 at 1:28:35 PM UTC-6 ip18 wrote:

When I first created my application, I used NSIS to create the installer for distribution. However, in the upcoming update of my application, version 1.3 I have made some changes to the application itself and as part of the changes I have switched to using Inno Setup. 

I would like to seamlessly update the installations of versions older than 1.3. One way I can check if the older version is installed is by checking if the uninstall.exe file is present (the uninstallation executable name for Inno is different so that's why I was thinking of this), and then do a silent uninstall before proceeding with the new installation. But I only found documentation for running programs after the installation is complete. I need it to be done before.

One approach would be to include code in your IS installer that detects the NSIS installation and cancel the IS install at that point with a message to the user instructing them to uninstall the old version first.

Wilenty

unread,
Jun 6, 2022, 4:23:45 PM6/6/22
to innosetup
Jernej wrote:
"- run the old uninstaller silently from the CurStepChanged(ssInstall) event function in [Code]"

Instead of "CurStepChanged(ssInstall)", you should suggest of use the: https://jrsoftware.org/ishelp/index.php?topic=scriptevents&anchor=PrepareToInstall
Where it's possible to break the install execution and ask user to restart the computer if any file of current installation is currently used.

&:

"I suggest you don't run the old uninstaller, and instead delete it with [InstallDelete], and remove the old uninstall registry info with [Registry] instead, this way you'll avoid the whole problem."

Why?


Bill wrote:
"One approach would be to include code in your IS installer that detects the NSIS installation and cancel the IS install at that point with a message to the user instructing them to uninstall the old version first."

I created example installer to show how to uninstall NSIS based installation, based (exactly) on NSIS installer from there: https://nsis.sourceforge.io/Download

It won't allows you to move forward if NSIS is not installed, so it detects NSIS installation...
Download the example installer there: https://cdn.discordapp.com/attachments/645144950672982027/983462906224058448/Uninstall-NSIS.7z

Jernej Simončič

unread,
Jun 6, 2022, 4:50:46 PM6/6/22
to Wilenty on [innosetup]

On Monday, June 6, 2022, 22:23:45, Wilenty wrote:


"I suggest you don't run the old uninstaller, and instead delete it with [InstallDelete], and remove the old uninstall registry info with [Registry] instead, this way you'll avoid the whole problem."

Why?

Because it avoids the whole problem with having to figure out when the NSIS uninstaller has finished (and can be done without needing to use [Code] at all).

 

-- 
< Jernej Simončič ><><><><>< https://eternallybored.org/ >


Much work, much food; little work, little food; no work, burial at sea.
       -- Cook's Law

Wilenty

unread,
Jun 6, 2022, 4:58:15 PM6/6/22
to innosetup
For first please check the example I had prepared, it correctly uninstalls installed NSIS program, it waits for the NSIS uninstaller to finish and it returns NSIS uninstaller exit code.
So, about what a problem you are talking about?
Reply all
Reply to author
Forward
0 new messages