Downgrading an MSIX-installer application after setting ForceUpdateFromAnyVersion - msix

We have an application that we distribute internally on a network share with an MSIX package. We make the MSIX package with the MSIX project type in Visual Studio. Users install it with the index.html page that is created.
We want to rollback changes in case an update goes seriously wrong, so I've created an .appinstaller template and use it to set the ForceUpdateFromAnyVersion flag.
My question is how does a user actually perform a downgrade? I've tried to browse to an earlier version in Windows Explorer and execute the .msixbundle file, but it tells me that a newer version of the app is already installed and my only option is to launch the currently installed version.
I've only just discovered this ForceUpdateFromAnyVersion flag last week and we create weekly releases, so the version that has that flag set is the current version. Is that the reason downgrading doesn't work?

To perform a downgrade, place the appinstaller file on the share near the MSIX/MSIXBUNDLE and instruct the users to install the application via the appinstaller file (double click the appinstaller).
Only then the downgrade scenario will work. The msixbundle does not contain the ForceUpdateFromAnyVersion and it's not aware of it unless you use the appinstaller, that is why, when you try to downgrade via the msixbundle you receive the error that a new version is present on the machine.
What you must consider is this: if the user installed the MSIX/MSIXBUNDLE first, and then you publish the appinstaller file with the old version on your share, the downgrade will not happen automatically, because the MSIX on the user machine does not know that he has to check any share for updates/downgrades. All of the auto-update options are defined in the appinstaller.
But if your users installed the application via the appinstaller first, you can then put a new appinstaller file on your share (and MSIX/MSIXBUNDLE of course) which points to a lower version, and depending on how you defined the check interval in the appinstaller file, the downgrade will be performed automatically..

From what I read (I didn't test it) it seems that indeed the flag needs to be present in the appinstaller of the version that is checking for updates (not just in the new version). So, with the next update you should be able to push an downgrade.
Here is a more details tutorial from Microsoft on MSIX downgrades.

Related

I'm trying to create an auto installer bot

I will place a fold with the installer in desktop then automate the installing process. Does the bot will also wait if the pc lags?
Why do I need to submit email/license etc every time I open the app? Please create a proper installer and how to create an executable problem without opening the g1ant edit?
G1ANT robot always finishes one action before it starts another one, so you don't have to worry about any PC lags.
Entering your email is required when you haven't yet activated G1ANT.Studio on your computer and it should happen only the first time or when you want to change your license.
Entering license key in order to open the G1ANT editor is required due to security reasons. This way you can make sure that only RPA developers can change your G1ANT code and no one unauthorized who doesn't know the license key can use it. But this feature is only in the production version. Developer version doesn't have this protection.
What do you mean by "proper installer"? G1ANT.Studio is so light (it weighs less than 150 MB) that .msi is not needed, you can just download it from G1ANT website and use it without any installation right away.
The G1ANT editor doesn't have to be opened for the scripts to be run, triggers work correctly if they're activated and G1ANT.Studio is running.

how ActiveX can be updated automatically at client machine

I have created an ActiveX control which is installed in the client machine. Now I have made some changes in the ActiveX control and now want that Changed ActiveX should be updated in the client machine automatically.
I have changed the version of the setup file from 1.0.0 to 1.0.1 and "removePreviousVersion" to "True" but still it is not asking for update.
Should i change the AssemblyVersion and AssemblyFileVersion of the assmeblyinfo.cs file.
Am I missing something to change the product code or update code or version?
"asking for update" must be your implementation. ActiveX/COM-s do not update automatically. You can run Setup to preinstall the new version.
However you can implement some service/background process which checks for new version via internet. There must be web/file server connected to internet which shares some small file (e.g. text or XML saying which is the latest available version).

Using WiX, Windows Services are not installed after a downgrade

While testing the downgrade functionality of one of our WiX-built MSIs, I have noticed something odd.
I have allowed downgrades in the MajorUpgrade element and I have scheduled that element to be afterInstallInitialize (but I have tried it thoroughly with afterInstallValidate and I experience the same problem; we can't have it after that action, but I thought I'd test it).
Many of the files (e.g. the DLLs in our Service's bin folder) are of a higher version, with each release; therefore, the version we are downgrading to includes files of a lower version. Yet all of those files are installed fine, during the downgrade, apart from the Service EXE files; further, the Services are also not installed in Windows.
Considering all of the above, after spending two days on this problem, and after much searching, I appear to be at a loss.
I have tried two things that seem to provide some hope:
1) I have tried setting the REINSTALLMODE property to amus. This ensures that the EXE files are installed, along with the Windows Services. But most things I read about that property warn against using it, and I even have to surpress ICE40, in order to get my package to build, when setting that property. This all concerns me, as I am not sure what negative effects could be missed, if I use this property in my MSI files.
2) When I remove the KeyPath attribute from the File elements that mark up the Service EXE files and place that attribute on the Component element instead, the Service EXE files are installed onto the system during the downgrade, but the Services are still not installed in Windows. After looking into this, it seems that the KeyPath attribute must be on the File element, if I'd like Services to be installed. So it seems to me as if this idea will not help.
Any help or advice would be very much appreciated. We really could do with providing downgrade functionality.
Thank you all for your time.
MSI is essentially opposed to the idea of downgrades. Once a file is on the machine, MSI tries very hard to keep the latest version of the file around as, among other reasons, downgrading the file can re-introduce a security vulnerability. I'd suggest not directly supporting downgrades; instead, you can show a message that tells the user to uninstall the higher version first.
My solution was to use Burn to provide the 'downgrade' functionality using a custom bootstrapper application.
The bootstrapper detects, downloads, and then installs the new version. In the case of a downgrade it performs an uninstall prior to the install. However, this requires that you execute the bootstrapper of the currently installed version to get the ability to uninstall.
You then also need to worry about any state that will be removed as a consequence of uninstalling, this needs to be preserved the same way as you would during an upgrade.
Using Wix, to allow downgrading and still have the Windows Service install properly on downgrade, use the following combination:
<Wix ...>
<Product ...>
<Property Id="REINSTALLMODE" Value="amus" />
<MajorUpgrade Schedule="afterInstallInitialize" AllowDowngrades="yes" />
I was also using WixSharp to generate the .wxs file and used this code to do so:
// https://learn.microsoft.com/en-us/windows/win32/msi/reinstallmode
// a = Force all files to be reinstalled, regardless of checksum or version.
// m = Rewrite all required registry entries from the Registry Table that go to the HKEY_LOCAL_MACHINE or HKEY_CLASSES_ROOT registry hive. Rewrite all information from the Class Table, Verb Table, PublishComponent Table, ProgID Table, MIME Table, Icon Table, Extension Table, and AppID Table regardless of machine or user assignment.Reinstall all qualified components.When reinstalling an application, this option runs the RegisterTypeLibraries and InstallODBC actions.
// u = Rewrite all required registry entries from the Registry Table that go to theHKEY_CURRENT_USER or HKEY_USERS registry hive.
// s = Reinstall all shortcuts and re-cache all icons overwriting any existing shortcuts and icons.
project.AddXml("Wix/Product", "<Property Id=\"REINSTALLMODE\" Value=\"amus\" />");
// Allow downgrading versions
// https://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html
project.AddXml("Wix/Product", "<MajorUpgrade Schedule=\"afterInstallInitialize\" AllowDowngrades=\"yes\" />");
See also:
https://learn.microsoft.com/en-us/windows/win32/msi/reinstallmode
https://wixtoolset.org/documentation/manual/v3/xsd/wix/msiproperty.html
https://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html

Service installed on Windows 7 machine is not reading from its config file

I have a .Net 3.5 web service that installs perfectly on my old XP box. I recently got a beautiful new Windows 7 box and everything has been working wonderfully. Yesterday I remembered that I need to instal this service on my new box and attempted to perform the install.
After the install I did a quick test and it seemed to be working correctly. Later in the day, I went into the config file and made a small change. After restarting the service I was dismayed to discover that the change was NOT being picked up by the service and it continued to use the old values.
Can someone explain how this is possible? I am totally befuddled here.
You've most likely been a "victim" of Windows Backward Compatibility (aka UAC Data Redirection).
When a program running as non-admin tries to write to config files located in Program Files, Windows redirects the write to another (user local) directory. That means, a user can seemingly write the file, but another user will see the original, Program Files, version.

Automatic program update and Windows 7

We have a suite of programs that check for new versions at startup, and then download new versions to run if required. This is obviously a problem in Windows 7, when it is locked down as a 'standard user', as they can't write to the c:\program files directory and below. Anyone seen a example of an application that gets around with issue ?
Our applications are written in Delphi, but an example in any language would be useful.
Thanks in advance
Update:
We already have a system for determing whether a new version exists, the only problem is the download and install (if required), as this requires elevation. I can't think of a way that doesn't require an elevation prompt, or our users to reduce their security settings.
Update 2 :
I've asked a subsequent question, rather than adding a new one here
There are two options for application installation:
Application is available for all users: installation or update requires elevation for Windows Vista and up
The application is available for one user: install or update the application in the user profile in %LOCALAPPDATA%, no elevation is required
Ad 2: Google Chrome does this. It installs the .exe here:
%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe
--jeroen
Typically what you will see an application do if it needs to escalate permissions is something like this.
Application determines if upgrade is needed
Application launches an "updater" service that requires "Administrator" permissions
Application updates itself with this updated
Application re-starts
This is a pretty common scenario, especially since to update your own DLL you need to go to a secondary process anyway.
Here are some tips for you to get around updating challenges:
If your file is names 'update.exe' or 'install.exe' then it will automatically force a UAC elevation prompt. This is an easy way to make existing software bypass Windows Vista/7 permissions.
It is not a good idea to have the update checking and update process managed from within your application. The problem is that your app is likely to lock files and need updating itself. An external app should manage your updates.
The simplest update solution is to make an HTTP call that checks for the current product version number, and then download the installer binary if necessary. This won't give you any flexibility in updates, but it is a quick and easy solution.
Our company sells software that specifically helps with automatic updates on Windows 7 UAC (you can visit AutoUpdate+ by clicking here: link text). The best reasons for using a third party solution - any solution - are that you will have more flexibility with your updates and also avoid the finicky challenges of supporting different Windows releases.
Or you can have it so that the user runs a launcher app.
The application uses the LOCALAPPPATH\ folder to store a cache of the main application.
Launcher checks to see if the internet has newer version of file(s) than the cached file.
Launcher launches the cached application in LOCALAPPPATH
Your app can check if a new version is available on the remote server. If it does, then it can download update files in one of user-specific folders, like user's temp folder. You can get address of such special folders using SHGetSpecialFolder API function.
Once the download is done, you can pop up a dialog box telling user that you are ready for update. If user agrees with update, then you can run the updater process with elevated privileges (as administrator), and updater process can replace existing files in your installation path with the ones already downloaded in user Temp folder. To run your updater as administrator, you can use ShellExecute:
ShellExecute(0,'runas','notepad.exe',nil,nil,SW_SHOWNORMAL);
When updating is done, your updater process can restart your app.
You need to have a separate executable to the updating work. The updater needs to have a manifest that marks it as requiring elevation.
See: http://msdn.microsoft.com/en-us/library/bb756929.aspx
If your application uses MSI (Windows Installer) for its installer, then User Account Control Patching, if properly configured, can let you install updates without elevation.
If your installer wasn't run under admin - you don't need any additional rights to install update.
If your installer was run under admin - then it can create a task in Task Sheduler. Say, run this task once a week, under this account (admin) and with highest privs. Task will be your updater. Simple.

Resources