MSI OriginalDatabase and SourceDir properties and replacing MSI file - installation

I place update.msi file let's say in C:\installs and run it. After some time I replace update.msi and repeat installation (sometimes it is the same application - updated, and sometimes completely different one).
From MSI log files I can notice it keeps track of OriginalDatabase, SourceDir, properties.
Can this have any implications when for example I want to uninstall one of the applications installed in a described way?

Related

Adding an external CAB to an MSI with an internal one

I have a visual studio installer (vs2015) that installs an application. I want it to also install a set of configuration files, the contents of which vary by physical install location, that will be delivered as a cab file in the same directory as the msi. The cab has a known set of files that will be distributed across 2 folders in the install location and is created by a different project than the installer. How do I get the msi to install both its internal contents and the contents of the external cabinet file?
Wise Package Studio
I actually successfully updated MSI files with new files to install using Wise Package Studio back in the day. It added a CAB file to the Cabs table (I don't know if this table is actually a Wise "view" or a real MSI table - it seems missing from Orca if all CABs are embedded in the MSI). There is a corresponding entry in the Media table where the LastSequence value (in the Media table) describes which CAB contains what files. In the File table you will find a field called Sequence which specifies the "order" of the files listed. Essentially your new files will be at the end of the "order" and hence in a new CAB. A bit involved the whole thing.
However, I successfully got Wise Package Studio to both embed a new CAB file, and to use an external CAB file to install the new files during installation, but I don't have the procedure documented and don't recall all the steps. Moreover I don't recommend the procedure - in fact I would never use this approach now. It was just used at the place I worked at the time. In most cases we used a transform to add this content to the main package, rather than hacking the MSI itself.
MSI SDK: Including a Cabinet File in an Installation
The procedure to add a CAB file to your MSI is documented in the MSI SDK here: Including a Cabinet File in an Installation. Quite involved - as I said, but definitely possible. As you will see the lack of a # flag at the start of the CAB name in the Media table indicates an external CAB file.
So I suppose, in short:
Add a new entry to the file table, set the Sequence number to +1 from the highest sequence File entry already there. I would add a new, corresponding entry in the Component table as well.
Add a new row to the Media table, specify the number you set for the file in the LastSequence column. Add the name of your cabinet file to Cabinet. Make sure to not prefix the CAB name with #.
Wise would also add entries in the MsiFileHash table. Not sure if this is required or not. Pretty sure it is not required to add entries here.
As you will see in the linked MSI SDK article, you can embed the whole cab following the last few steps listed in the linked MSDN content.
I wish I had time to test all this, but I don't. Which brings me to the next point:
Default / Instantiate Your Settings?
When I see questions like these I invariably ask myself: what is in these files? Are they "trivial settings" that could actually be defaulted instead of hard coded in config files? This has saved me a lot of work, many times.
The deployment of settings and data files have always been problematic with both MSI and legacy style installers. My philosophy of deployment for such files is to treat what you install as "read-only" and then you copy them to per-user locations or set them in HKCU on application launch, using some sane process of obtaining appropriate values (from settings written to HKLM during installation, retrieved from the user, retrieved from the Internet, etc...). Please see this longer answer on the subject: Create folder and file on Current user profile, from Admin Profile. The best approach, in my opinion, is to retrieve settings on launch from an online database (as you will see if you read that linked content), but that is involved.
It's not clear precisely what you mean, but you cannot alter the MSI to unpack all the files in your separate CAB as if they were in the MSI as the other files are. There is too much internal data on the files inside the MSI file, in the file table, component table, and so on.
So if the CAB file is in the same location as the MSI file then you could create a custom action to copy it to the target system, and unpack if you want. The copy can be told where the MSI location is by using the [SourceDir] property or the [OriginalDatabase] property OriginalDatabase property
You'd parse that location to get the path and then do the copy to the TARGETDIR location.

MSP file extracts only files that belong to new components

I've created a patch with Advanced Installer by using an old (target image) msi and the new one (upgrade image). Inspecting MSP file I've discovered that it contains both modified and completely new files. The problem is that during the installation it installs only the "added" files. Existing files are ignored. I've already tried MSIEXEC switches like:
REINSTALL=ALL
REINSTALLMODE=sumo / aums / omus etc...
UPGRADE="Yes"
IS_MINOR_UPGRADE = "1"
..in different order and combinations (i.e. "REINSTALLMODE=aums REINSTALL=ALL"), so don't reply or comment just by telling me to try REINSTALLMODE=omus or something similar.
When creating a patch there is a set of rules that need to be followed, have you checked those? Breaking one of those can lead to unexpected behavior, such as the one you are now encountering.
To check for the rules you can start with a diff between the project files, as they are standard XML ones, and check for their product code, component GUIDs, etc... For example folder synchronization is a common problem encountered when a patch is created, as this changes the component GUIDs.
For some odd reason all the core components (exe, dlls) I wanted to update were set to "Do not register this component with Windows Installer".
I suppose this is some kind of project bug, because it's very old and was migrated through different Advanced Installer versions (7, 8 and 9).
Anyway, I was not able to update my application correctly even with a fixed patch. Windows Installer kept on asking me to browse to target image msi file (cached installer of the previous version).
However not all of my customers keep those files (usually this cached files are stored in %APPDATA% folder). So I found a workaround:
I've applied "Hash files" option in order to create a MsiFileHash table
I've packed my msp patch in a bootstrapper (exe file) that starts it with the TWICE with following command-line parameters:
first time:
"myPatch.msp" /n {150F6CE2-8C12-414B-9377-F087A62E6B67} REINSTALLMODE=c /qb
second time:
"myPatch.msp" /n {150F6CE2-8C12-414B-9377-F087A62E6B67} REINSTALLMODE=dep /qb
REINSTALLMODE=c switch forces file compare algorithm based on hashes, so it doesn't require the original setup sources anymore
REINSTALLMODE=dep restores all the other missing files, files with unknown or different (from target) version
I hope this workaround will be useful to people that use MSI/MSP authoring tools other than Advanced Installer

Make Windows Installer ignore a running process

Using Installshield 2010 and Basic MSI project.
I have an exe that was previously installed by my installer. That exe needs to be running during an installer upgrade. Is there a way to guarantee that the installer won't try shutdown the process? Basically, I would like the behavior to be : If file doesn't exist, lay it down, otherwise ignore it.
I have made the exe a key file in a component and set it 'Never Overwrite' to true. Should this give me my desired behavior ?
Never Overwrite will be used by future installers to determine if the file will be overwritten or not by other MSI packages. Basically, this attribute should have been set for the installed EXE.
A good approach is to use a file search to determine if the EXE exists. The search property can then be used to condition the new component.
Windows Installer doesn't automatically close applications, but it does show a FilesInUse dialog which offers this option to the user.

How to prevent Installshield from removing files?

I am developing a package using Installshield 2008 Primer Edition and Project type is Installscript MSI project.
The problem I am facing is during installation I am installing some of the files to the following location C:\Program Files\Company\SystemFiles from this location I am copying and adding the set of files into System32 folder, it contains DLLs and OCX files, copying into the System32 folder has been done using Installscript.
Due to this during uninstallation, the installed file is getting removed from System32 due to this other dependent application which requires the same set of DLLs have stopped working.
I have approached Installscript to copy files from ProgramFiles to System32 Folder rather than using built-in options because we have an issue during the upgrade in order to avoid that I am using Installscript.
Even I have tried several workarounds like setting the file attributes after file copies to System32 using Installscript like FILE_ATTR_SYSTEM which sets the system attribute but still files are getting removed during uninstallation.
Any idea how to give file attributes as PERMANENT or SHARED; will this help, and if it will, then how can I set it using Installscript?
I have 2 ideas
1)I think you can use SHARED option as this wont remove the files while uninstallation.
2)Also when i was facing similar issue , what i did was putting all the required files in the installation directory itself so that while uninstalling only the installed files will be removed.(I know this is not a best solution)
(NOTE:I have worked on Install shield some 6 years back and so remember only certain things)
You can also disable logging from Install Script. This will make the installer "forget" that it installed specific files groups or features.
You should make sure to enable logging once again after you have copied the files that you want to permanently leave on the system.
If you don't remember to enable logging after you have disabled it, your uninstall process may not work correctly.
Syntax is as follows:
Disable(LOGGING);
//Add code to copy your permanent files here
Enable(LOGGING);
For InstallScript projects:
To prevent the files in a particular Component from being removed during uninstall:
1-Select the Components view from within the Organization folder.
2-Select the component that contains the files you do not wish to remove during uninstall.
3-Change the "Uninstall" property in the right pane to a value of "No."
For MSI Projects:
To prevent the files in a particular Component from being removed during uninstall:
1-Select the Components view from within the Organization folder.
2-Select the component that contains the files you do not wish to remove during uninstall.
3-Change the "Permanent" property in the right pane to a value of "Yes".
I see this is an old question but I just came across this. Seems to be a common problem. One good solution is to stage the files to a private directory mostly program files and then have a custom action do the copy and register (ocx etc). Installshield remembers what it copied so it tends to remove them. Do not disturb anything else like logging (my recommendation). Set conditions on the custom action so that it doesn't run during Uninstall.
Although sometime back I did another weird implementation which only programmers are used to doing.. Packed the files as resources and created my own code to extract and deploy (Something that Process Explorer kind of tool does). There were certain use cases that warranted this kind of implementation. But again this is complicated and obviously reinventing the wheel. Unless you are good with C/C++ and Windows API this would be difficult. I would still suggest you stay away from this kind of implementation because it is also considered a "virulent behavior". Yet, so far I never got warnings from the Anti-malware products.

Freeware tool for creating a single file installer from an msi file + config file (thats easy enough for an End-User to use)

My installer requires there be two files in the same directory in order for it to install.
The installer (.msi file)
An organization specific config file that the installer copies. (This file is customized by the organization and then distributed to it's end users).
Since there are two files, the file has to be distributed as a zip file. Which presents the issue of if a user tries running the .msi without actually extracting the zip... only the msi file gets extracted. I am able to detect the issue in the install process and tell the user they need to unzip the file... but you know how noone actually reads error messages.
So, I'd like to make it more foolproof and so i was wondering if there was a simple tool that i could let my customers (ie the organization) be able to make modifications to the config file and when finished create a .exe file which when clicked would extract to a temp folder and then run the msi. I know there are solutions for this which require commercial software. I'm wondering if a simple freeware tool exists that can do this.
Edit: Accepted Solution Notes:
The one issue i ran into is the iexpress wasn't designed to be used for .msi files. As a result on the step that asks you for the Install Program. It's a combo box which if you had added a .exe file in the previous step could just select the .exe file from. Instead you have to manually type in
msiexec /i yourinstaller.msi
I was very pleased to find such a simple solution that's built in to windows. The only way this could be better is if it allowed for wildcards so that your iexpress project would be able to handle changes in the msi file's name which occur with each version. And defaulting the Install Program to the .msi file. These minor inconveniences are offset by the fact that end user wouldn't need to install any new software to create the package so I have stopped looking for other tools.
You could try using iexpress.
It enables you to package up a set of files which can be extracted, with the option of running an installation command automatically after extraction. It also has options to enable you to prompt users about things, show a EULA, restart the computer, etc..
I believe it comes as part of Windows (part of IE?) - try running iexpress.exe from the run dialog to get the UI.
The Wix project has a bootstrapper and packager for dealing with this kind of thing.
I've used wix a lot but haven't really looked at the bootstrapper/packager much - last time I had a quick look it wasn't really usable but that was a long time ago so it may be better now.
I'm guessing that the config file is something like a properties file, and that you want users to set the values of the properties "foo" and "bar". You don't need a separate tool to update the file.
I would do this:
Put one or more dialogs in the install that ask the user what the values of foo and bar should be, and set a couple public properties accordingly.
Write a custom action that writes the config file out to whatever location you want, including whatever values you want for foo and bar. This would be pretty easy in vbscript.
Put the custom action somewhere in the execute sequence (ideally as a deferred execution action, since you're making changes to the system).
Add an entry to the RemoveFile table, so the config file is removed on uninstall (assuming you don't want it to be left behind.)
Add an entry to the LaunchCondition table, to prevent users from doing a silent install. Or if you want silent install to be allowed, make the names of the public properties that hold the config data known, and make them part of the LaunchCondition. You would block "msiexec /i myapp.msi", but you could choose to allow "msiexec /i myapp.msi FOO=Something BAR=SomethingElse".

Resources