Detecting file modification with install4j - installation

We ship a config file as a part of our installation that we create via install4j. Suppose the user is doing an upgrade installation when we ship a new version of the product. Is there any way to determine if the user has manually modified the file after last installation ??
We need to detect if the user has modified this file, and then merge the changes that the user has done with the new changes that we are introducing by the update.
Any pointers / ideas would be greatly appreciated.
TIA

As of 5.1.11, install4j does not support this kind of content-based modification detection. Modification detection only takes file modification times into account.

Windows installer compares a file's create and modify dates. If they are different the file has changed.
I believe you can solve this in a better way by writing the config file using the main application executable using "internal defaults" in your application instead of a base config file delivered via your setup. You can then re-apply all internal defaults to the existing file, add any new updates whilst keeping user changes where possible (sometimes you want to override what has been changed?).
The more intelligent an application is in its configuration and maintenance of settings, the less deployment problems you will see.

Related

VS2015 Setup Project not updating Access Database included in package when reinstalling

I'm trying to build a Visual Studio Installer Setup Project that deploys multiple C# projects and some other files. Included in these other files, there are Access Database with forms that needs updates.
To illustrate the problem, I simplified it :
1- Create a new Access Database file, add a simple form to it with a button and a label and save it.
2- Add the file to the setup project;
3- Set DetectNewerInstalledVersion and RemovePreviousVersion to true
4- Build the project.
5- Run the setup executable.
To that point, everything has worked fine
6- Reopen the Access Database file, add a button or a label to the form, save it.
7- Change the Version number of the Setup project, and at the same time the ProductCode as suggested by VS2015.
8- Rebuild the setup project.
9- Reinstall the software.
Expected: the Access data should have been updated with the new button/label.
What is happening: The file hasn't been updated.
Why is that ? I've seen people talking about the Assembly version number of projects included in a setup project, but that's not my case since I'm not deploying the ouput of a project. I'm simply deploying a file that should have been removed during the uninstall process.
If I do the exact same steps as described before but with a text file in which I add text, it works fine, but for some reason in does not work with an Access Database.
What's wrong ?
If you install a data file, and then run a program that updates it you've added user data to that file, or database. The file overwrite rules don't allow a modified data file to be replaced in the kind of update that VS setups do:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370531(v=vs.85).aspx
Basically it would be a bad idea to ship a product that installs a database that the user updates with potentially large amounts of data, only to have the new version of the product delete the entire database. It's not clear to me how your app deals with updates (do you want that added button/label just to be completely lost, or do you save them in some way?) so recommending a solution is difficult, but maybe you need an uninstall custom action to delete the database, or on an upgrade you add the updates to the existing DB instead of removing it and starting again.
I found a solution. The file wasn't updating because the modified date had changed.
From MSFT site:
Nonversioned Files are User Data—If the Modified date is later than
the Create date for the file on the computer, do not install the file
because user customizations would be deleted. If the Modified and
Create dates are the same, install the file. If the Create date is
later than the Modified date, the file is considered unmodified,
install the file.
Since I had two Access databases (front-end with the forms, backend with the data tables) and needed only one to be updated (the frontend where the forms are), here's the workaround:
1) Change REINSTALLMODE property to amus instead of the default omus. It will force the reinstallation of all files. To do that, I used a PostBuildEvent as explained here.
2) Set the backend file property Permanent to true
3) Add a Launch Condition: Search Target Machineto check if the backend file exists on the computer. Name it something like BACKENDEXISTS
4) Add a Condition value to the backend file in the File System view to install the file only if it hasn't been found by the Launch Condition. In this case, it will be not BACKENDEXISTS. If this is a first install, it will install the file because it hasn't been found. If this is an update, it will find the file because of the Permanent property and will not replace it.

Incremental auto online update with Install4J

I need some help regarding Install4J and the auto online update function.
We have a JRE bundled Install4J installer which works fine. We use the auto online update functionality which works fine, too. All this functionality in integrated to a continuous integration process in TeamCity.
Unfortunately the update installation setup file has a size of around 100MB which is inconvenient to download if we only want to apply a patch or a minor update.
As far as I have understood from other similar questions and the Install4J documentation the right way to deal with that is using a second project file with another application ID and setting up an Add-On-Installer which only contains relevant files and points to the full installer application ID.
To enable the auto online update functionality I have to upload the update.xml file from the Add-On installer, am I right?
By the way, does the Add-on online auto update procedure automatically detect the locally installed version correctly?
But in that case we have to adapt the add-on installer each and every time we are deploying a new patch or minor feature which is difficult to implement in the CI process.
Is there a way to configure an Install4J installer so that it automatically gets the information online which elements have to be updated so that the download size is as small as possible and we could just use one default add-on installer which contains all sources beside the JRE bundle?
Something like an online incremental update procedure which is managed internally by Install4J?
Thank you.
You should never use the add-on installer for updating, because it cannot change the version number.
In order to get smaller update installers, you create a second project where the distribution tree only contains the changed files - or at least does not contain some large files that did not change. To do that, you simply copy the original installer and delete the files in the distribution tree that you do not need to update.
Then you build two sets of installers, those for a new installation and those for the update.

MacOS X: Update software from dmg installer

I have a small software for MacOS with a simple dmg installer (Open, drag and drop to Application folder, you know). My problem is, that the software writes a small ini file inside the .app package and if I update the software, this file is lost, because the old package is removed before writing the new one.
My question is, if any of you know an elegant solution for this. The user should be able to save the file in any place e. g. desktop and the ini file should be moved into the new package. I don't want to save this file outside the .app package, because this would leave private data on the computer if the user just removes the package.
Thanks in advance!
Saving data into the aplication bundle is no good practice,
for future release, please implement another solution.
To solve the current problem, I can think of two solutions:
Add two files to the .dmg file
The new application.
Backuptool: An simple AppleScript to backup the file would do the job.
Make sure to notify the user to run the backup before replacing the application.
The user might however forget to run the backup, and loose data.
Create an installer
Another option would be to write an installer using PackageMaker.
PackageMaker provides options to run scripts before updating the Application.
Add an pre-installation script that backups the data.

Problem with an MSI distribution

So I am continuing testing and releasing changes to my app and I have come across a pain point that I am unsure how to deal with.
First off, my app uses a SQL Server CE database to store information and I need to be able to make changes to this db so I've created an internally updating process that runs whenever the application runs to make sure the db is up to date.
The crux of this internal update process is another SDF file named DBUpdates.sdf that contains all of the db schema changes that need to be applied.
The problem I am having is that the MSI distribution I created will not overwrite this file. It appears that when SQL Server CE opens this file, it changes the Modified date/time of the file. This is a flag to the MSI process that the file has changed, and that it shouldn't overwrite the file. Well now I am seeing that my db changes aren't being applied, because the MSI process thinks the user has changed this file.
At this point I am kind of stumped. I was planning on using an MSI distribution but maybe I can't. What do you think?
What about storing your .sdf as an embedded resource in your executable, and then extracting it to a temporary location on disk (as necessary) and perform the updates.
Unversioned files with MSI can be a bit difficult to handle if you need to force the installation of the file. You can see this previous question, for some ideas, How to add a version number to an Access file in a .msi.
The question contains a link to this blog post, http://blogs.msdn.com/astebner/archive/2005/08/30/458295.aspx, which suggests the way I prefer to deal with this problem. Add the .sdf file to be part of your executable's component. The downside to this is if someone delete the .sdf file, but not your executable I don't think a repair of the application will catch this. If your using Visual Studio to create your MSI files then this may prove a difficult solution to implement. I strongly suggest your check out WIX in that case. It is a better MSI build system.

C# Deployement retaining files over an installation

I have created a Setup and deployment project using the Visual studio and install the setup.
After i install the setup it copies a few files(XML) which on using of the application are configured programmatically .
Now , If the user is reinstalling this setup again i need to ask the user whether these configured files need to be overwritten or be retained ??
Any idea as to how this can be accomplished ?
Thanks & Regards,
Fran
Look into file versioning rules for Windows Installer.
In short, assuming that these XML files you refer to are unversioned text files, MSI will compare the Created and Modified dates and will not replace the updated XML files which you say are updated programmatically (post-install-time).
I would suggest several other variables you need to consider to make sure things are working as you expect: major vs. minor upgrade, and the REINSTALLMODE property.
I find that the best way to approach this kind of scenario is to implement the "preserve changes" logic in your application as opposed to via the setup. This avoids complicating your setup and yields greater control of the config process since all logic is embedded in your main EXE file. This means you can step through the process and debug it the normal "development way".
To achieve this you can install your "base config" files to a read-only location such as
%ProgramFiles%\MyCompany\MyApp\MyConfig*.*
Then your application can detect on launch whether existing config files exist in the user profile (or in a writable shared location), and ask the user whether the new config files should overwrite the existing config or not. You can also easily implement backup functionality for the old config.
In order to ask the question only once per user after deployment, the normal apporach is to flag HKLM with the latest installed version of the application and then write a corresponding flag in HKCU when the copy operation has completed or the user dismissed it:
HKLM\Software\MyCompany\MyApp\Version = 2.0.0
HKCU\Software\MyCompany\MyApp\Version = 1.0.0
In the above scenario version 2.0.0 of the application has been installed, but the per user config copy has not run for the user in question yet. Once it has run the HKCU version will be set to 2.0.0 and the operation is not run again until HKLM is incremented.

Resources