Is there a way to disable auto-update without re-running the installer? - install4j

We have an installer with a separately selectable auto-update feature.
Normally, if a customer wants to switch that feature on or off after the installation has completed, we tell them to re-run the installer and correct the setting. (Tested, works.)
Now a customer has a problem: Their corporate IT prepared an installation package that (mistakenly) has auto-update installed, and said IT refuses to put out a corrected installation package.
So the question is:
Can I give the customer a reasonably future-safe way to disable auto-update - say, by modifying a registry entry - without having to re-run the installer?

On Windows, the registry key
HKEY_CURRENT_USER\SOFTWARE\ej-technologies\install4j\installations
contains values with the names updateSchedule<application id>. If you locate the one for your installer, you can change the value data to "never".

Related

Disabling auto updates install switch?

In my current environment VsCode is being deployed to users through SCCM so they have the ability to install the app without admin rights. The current installation supports switches such as /Silent etc, but doesn't seem to have any other switches that would define auto updates to be off by default when the app is installed. The reason for this as I'm sure you're all aware VSCode will prompt the user letting them know there's an update avaliable. Done some digging already and as detailed, you can change the settings.Json file to disable the updates, which would be great if this was a 'system wide' i.e (C:\Program Files\Microsoft VS Code) settings file, but as detailed Here it points to %appdata% (User settings).
So, in theory you could query the user on the install and then just do some powershelly magic to chuck the required json data into that settings file and the user would be away and wouldn't have to manually turn off auto updates However SCCM installations install as an elevated account (system) not as the individual user running them so it doesn't appear feasible to manage it that way.
So fundamentally if there was a way/switch that would allow the auto update feature to be disabled on install or as a post install step I'd be very grateful for any clues on how to achieve this.
Thanks!
To achieve this with SCCM you can do the following (I will describe this for a package\program it is however also possible to achieve with an application, the options are pretty similar there):
Create a installer program the same way you would if you did not want to deploy settings (something like VSCodeSetup.exe /VERYSILENT /MERGETASKS=!runcode as your commandline and in the programs "Environment" tab select "Run with administrative rights")
Create a second program that copies (or creates) a settings file in the way you want it to %appdata%
In this second programs options in "Environment" set "Program can run:" to "Only when a user is logged on" and "Run mode" to "Run with user's rights"
On the "Advanced" tab set "When this program is assigned to a computer:" to "Run once for every user who logs on"
Deploy both programs to your collection
With this setup SCCM basically does what you want split into two different setups for the respective rights needed. There will be short times where the program is installed and the settings are not yet applied (can be shortened by setting "Run another program first:" in your config setup to the base setup but this makes things a little more complex and still if a new user logs in some time during a windows update job there will be delay until the settings are deployed) but the only way to guarantee that there is never a time where the settings are not applied is by replacing the default program start with a script that sets your options.
The settings JSON (likely the one which is being deployed with SCCM) just needs this entry:
"update.mode": "none"
While by default it has the auto-update channel enabled:
"update.mode": "default"
A post-install script could do that - but while it's located in %appdata%, the user still can change it.

In Install4J is it possible to update the sys.preferredJRE variable?

I have an installer whose purpose is updating the max version of a JDK for an existing installation (we require JDK, not JRE), and pointing the existing installation to run with the later version of the JDK (which is user pre-installed and user-specified).
In the installer, I have code that calls JVM.setPreferredJVM() from a directory chooser form component. According to the API for JVMSelector, it says this method will "Set the preferred JRE/JDK for your application." According to the help docs on variables (sys.preferredJRE), "This variable will only be set after the "Install files" action has run."
When I run the installer, I see that the setPreferredJVM() method is called, but the sys.preferredJRE is not set to what I wanted, it still references the old JVM. This is a problem because my subsequent "Add VM Options" steps use the sys.preferredJRE variable.
I expected that calling JVMSelector.setPreferredJVM() would update sys.preferredJRE, but it does not. How can I accomplish this so that the user can set the preferred JVM/JDK during the install?
This is a bug, it will be fixed in 6.0.2. Please contact support#ej-technologies.com to get an interim build with the fix.

MSI, Repair runs but I don't know why

I have an MSI package I maintain with Installshield 2012 Pro.
The package was created a few years again and requires periodic maintenance as new versions of the application is installs are released by our development team. This MSI has been used in many locations, on many machines without issue.
At one customer location, they've install about 20 copies of the application on 20 machines. Each machine is built exactly the same.
Periodically, for an unknown reason registry entries relating to that application go missing. Not all of them, a select one or two... the same entries always go missing.
We so far have failed to track the exact root cause, however one of our support engineers noticed the MSI repair dialogue appearing when they opened the application shortcut. Following this, the registry entries went missing.
On each instance of the registry entries going missing we have removed the MSI from the c:\Windows\Installer directory. On machines we've made this change too, the registry changes so far have not disappeared again.
This leads me to think the MSI is somehow removing the selected registry entries during the repair, but I don't understand how.
There are at least 50 registry entries under the same key as the entries that get removed. (these are created by the application not the installer)
The MSI package doesn't insert any keys at all during install
There are no custom actions at all
I only have one key file set in the whole MSI, and this is for a component installed in Windows\system32
None of the shortcuts are 'Advertised'
There appears to be a clear link between removing the MSI from the Installer directory and no further occurrences, but I fail to see what in my MSI could cause specific registry keys to disappear.
I realize the exact reason this this is subjective to my MSI or the customers systems, so as generally as possible I ask:
Why would Windows launch the MSI repair function, considering the above
Can an MSI alter the registry, considering the above
Is there anyway post installation of an MSI to disable the auto repair function for this MSI?
How should I alter the MSI to ensure auto repair doesn't occur?
Thanks
Start by proving whether the auto repair is related to your product. Check the application event logs for the component id that caused Windows Installer to kick off the auto repair. Then, if it's part of your installer, figure out why.
It seems unlikely that your MSI would alter the registry. Although you do not specifically say there are no RemoveRegistry table entries, it's hard to imagine any snuck in accidentally.
There are only bad ways to disable auto repair (some global, some involving not registering your installer). Avoid them.
First figure out what's wrong. Then figure out how to fix it. For instance if in step 1 you determine the component triggering auto repair is part of your install, perhaps set the logging policy on a machine where this occurs so you can get a verbose MSI log.

Uninstall exceptions in InstallShield

I have a setup project with InstallShield 2010. I'm deploying a configuration file during installation. However, when uninstalled, InstallShield decides to delete it (which is normal).
The question is, is there a way to keep the file on the hard disk even after the application in uninstalled? I don't want to reconfigure the application every time the user uninstalls/installs.
Edit: I'm using MSI project.
You don't say what project type you are using. Either way, put the config file in it's own component. For MSI projects, set the Permanent attribute to true. For InstallScript projects, set the Uninstall attribute to false.

Can I control the location of .NET user settings to avoid losing settings on application upgrade?

I'm trying to customize the location of the user.config file. Currently it's stored with a hash and version number
%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\
I want to it be agnostic to the version of the application
%AppData%\[CompanyName]\[ProductName]\
Can this be done and how? What are the implications? Will the user lose their settings from the previous version after upgrading?
I wanted to add this quoted text as a reference for when i have this problem in the future. Supposedly you can instruct the ApplicationSettings infrastructure to copy settings from a previous version by calling Upgrade:
Properties.Settings.Value.Upgrade();
From Client Settings FAQ blog post: (archive)
Q: Why is there a version number in the user.config path? If I deploy a new version of my application, won't the user lose all the settings saved by the previous version?
A: There are couple of reasons why the
user.config path is version sensitive.
(1) To support side-by-side deployment
of different versions of an
application (you can do this with
Clickonce, for example). It is
possible for different version of the
application to have different settings
saved out.
(2) When you upgrade an
application, the settings class may
have been altered and may not be
compatible with what's saved out,
which can lead to problems.
However, we have made it easy to
upgrade settings from a previous
version of the application to the
latest. Simply call
ApplicationSettingsBase.Upgrade() and
it will retrieve settings from the
previous version that match the
current version of the class and store
them out in the current version's
user.config file. You also have the
option of overriding this behavior
either in your settings class or in
your provider implementation.
Q: Okay, but how do I know when to
call Upgrade?
A: Good question. In Clickonce, when
you install a new version of your
application, ApplicationSettingsBase
will detect it and automatically
upgrade settings for you at the point
settings are loaded. In non-Clickonce
cases, there is no automatic upgrade -
you have to call Upgrade yourself.
Here is one idea for determining when
to call Upgrade:
Have a boolean setting called
CallUpgrade and give it a default
value of true. When your app starts
up, you can do something like:
if (Properties.Settings.Value.CallUpgrade)
{
Properties.Settings.Value.Upgrade();
Properties.Settings.Value.CallUpgrade = false;
}
This will ensure that Upgrade() is
called only the first time the
application runs after a new version
is deployed.
i don't believe for a second that it could actually work - there's no way Microsoft would provide this ability, but the method is there just the same.
To answer the first question, you technically can put the file wherever you want, however you will have to code it yourself, as the default place the file goes to is the first of your two examples. (link to how to do it yourself)
As for the second question, it depends on how you deploy the application. If you deploy via a .msi, then there are two hashes in the properties of the setup project (that the msi is built from), the 'upgrade code' and the 'product code'. These determine how the msi can be installed, and if it upgrades, overwrites, or installs beside any other version of the same application.
For instance, if you have two versions of your software and they have different 'upgrade' codes, then to windows they are completely different pieces of software regardless of what the name is. However if the 'upgrade' code is the same, but the 'product' code is different then when you try to install the 2nd msi it will ask you if you want to upgrade, at which time it is supposed to copy the values from the old config to a new config. If both values are the same, and the version number didn't change then the new config will be in the same location as the old config, and it won't have to do anything. MSDN Documentation
ClickOnce is a little bit different, because its based more off of the ClickOnce version # and URL path, however I have found that as long as you continue to 'Publish' to the same location the new version of the application will continue to use the existing config. (link to how ClickOnce handles updates)
I also know there is a way to manually merge configs during the install of the msi using custom install scripts, but I don't remember the exact steps to do it... (see this link for how to do it with a web.config)
The user.config file is stored at
C:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\<appdomainname>_<eid>_<hash>\<version>
<C:\Documents and Settings> is the user data directory, either non-roaming (Local Settings above) or roaming.
<username> is the user name.
<companyname> is the CompanyNameAttribute value, if available. Otherwise, ignore this element.
<appdomainname> is the AppDomain.CurrentDomain.FriendlyName. This usually defaults to the .exe name.
<eid> is the URL, StrongName, or Path, based on the evidence available to hash.
<hash> is a SHA1 hash of evidence gathered from the CurrentDomain, in the following order of preference:
1. StrongName
2. URL:
If neither of these is available, use the .exe path.
<version> is the AssemblyInfo's AssemblyVersionAttribute setting.
Full description is here http://msdn.microsoft.com/en-us/library/ms379611.aspx
(I'd add this as a comment to #Amr's answer, but I don't have enough rep to do that yet.)
The info in the MSDN article is very clear and appears to still apply. However it fails to mention that the SHA1 hash is written out base 32 encoded, rather than the more typical base 16.
I believe the algorithm being used is implemented in ToBase32StringSuitableForDirName, which can be found here in the Microsoft Reference Source.