InstallScript CA changes done in registry are not removed on uninstall - installshield

I have A Basis MSI project created with InstallShield 2018.
The setup include some InstallScript CA that modify the registry ( I should have done it inside a component but due to some limitation it's done by code )
Now I have located the CA between the InstallInitialize and CostFinalize action with NOT REMOVE="ALL" condition.
The code works well on install by while uninstall these changes are not deleted.
Should it work this way ?

That is just a condition that must be true at runtime. So it's basically saying do not run this custom action when uninstalling.
Since you're creating the registry values in your CA the MSI has no clue about them during uninstall. You'll probably need to write another CA to remove them on uninstall and condition it to run on uninstall (REMOVE=ALL)

Related

Preventing a user from uninstalling the application based on registry search

I have created 3 independent MSI files using WIX3.8
The first MSI package is the core package which installs the basic(Core) components.
The other two MSI packages are add on to the first MSI. I have put the necessary checks in place which will prevent a user from installing the add-ons if the basic components are not installed.
The problem now is how do I prevent the user from un-installing the core components when the add-ons are installed?
I have added specific registry keys while installing each MSI so that I can refer them.
I have spent over 2 days on Google and SO but could not find any solution :(. If I missed anything please provide me the reference link.
Any help is greatly appreciated.
Use the Upgrade element with the other addon components upgrade codes to detect the other products.
E.G. In your core components installer add something like
<Upgrade Id ="Addon Product A's Upgrade GUID">
<UpgradeVersion OnlyDetect="yes" Minimum="0.0.0.0" Property="ADDONADETECTED" IncludeMinimum="no" />
</Upgrade>
<Upgrade Id ="Addon Product B's Upgrade GUID">
<UpgradeVersion OnlyDetect="yes" Minimum="0.0.0.0" Property="ADDONBDETECTED" IncludeMinimum="no" />
</Upgrade>
<Condition Message="There are other products that depend on these components, aborting uninstall.">
<![CDATA[ADDONADETECTED OR ADDONBDETECTED AND (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")]]>
</Condition>
I would:
Add ARPSYSTEMCOMPONENT to those MSI files so they don't show in Programs&Features.
Assuming you allow normal major upgrades, make the bundle do the uninstall with a command line parameter such as BUNDLEUNINSTALL=1 and then have a type 19 custom action that prevents the uninstall from continuing if REMOVE="ALL" AND BUNDLEUNINSTALL<>1.
I'm not sure that a registry search provides a good solution. I would use a custom action based on MsiEnumRelatedProducts (upgradecode of other products using these components) to find the ProductCodes of those products. If you get some ProductCodes back then you can call a type 19 custom action to prevent the uninstall. In general Rick's suggestion is good, but I think the strategy you should go for is to use a bundle. This kind of thing: http://wixtoolset.org/documentation/manual/v3/xsd/dependency/provides.html

Getting InnoSetup to use uninstalled app's previous directory

A have an app that must be uninstalled before it can be upgraded (not something I can change).
Of course, the default directory for the new install should be where the previous version was installed. But since the app has been uninstalled UsePreviousAppDir doesn't work.
What would be the best way to get an uninstalled app's directory? Is there anywhere it is stored? How would a new registry entry be managed for this?
There is no way to find the previous location of the app after it has been uninstalled, short of asking the user to remember this and re-enter it.
However, a simple solution to this issue is to trigger the uninstall from within the upgrader itself -- UsePreviousAppDir takes effect when the wizard first opens, so it's safe to discover the previous app dir and uninstall at any point after that. The most recommended time to do it is from the PrepareToInstall handler.
Bear in mind that it still could be possible that you won't be able to find the prior path, either because the user manually uninstalled before running the upgrader or because the install failed, crashed, or was cancelled after it successfully uninstalled the prior version. So you'll need a backup (such as asking the user, or assuming some reasonable default) anyway.
Be very sure that you really do need to uninstall beforehand, though -- while there are a few cases where it is required (such as when the prior version was not installed with Inno -- in which case UsePreviousAppDir isn't going to help you either), most of the time you should just install over the top, using flags and [InstallDelete] entries to skip or remove old files as needed.

How to clean up registry settings with uninstall?

I have an installer which needs to add a key to Currentuser under \Software\Microsoft\Office\12.0\Excel\Options. It must be CurrentUser because excel does not look in LocalMachine. I have a customer that requires Admin rights for an install. I found that when the installer was run as the Admin user, the key was created under the Admin users registry settings. To get around this, I wrote a custom action which created the Excel key in Currentuser, and then copied the key to every other user currently logged on to the machine. This seems to work.
The problem i now have is on the uninstall. The registry key is left in place, which causes issues with Excel. What is the best way to get rid of this registry key on an uninstall?
I am using the Windows installer in VS 2010.
Currie
try installing and running Revo Uninstaller. Once it's installed, see if excel is still there to be uninstalled. In REVO, there is a step in the uninstall process where you check the checkboxes, in bold text, of the registry items to be deleted.
http://www.bleepingcomputer.com/download/revo-uninstaller/
(on the site, click "download Now" instead of the "download" button at the top (which is just a link to google leads).

Display additional dialog when application is in upgrade mode

I created a setup file which is working awesome.
Now whenever I rebuild an application without changing anything but Package Code is changed and then while I am going to install this version then a dialog will come "Upgrade Dialog" which ask me for upgrade an application.
Now in this situation I want to display an additional dialog created by me.
I am using the Insatllshield 2012 BASIC MSI project type.
I solved this problem.
There are two properties exist in Installshield named "IS_MINOR_UPGRADE" and "IS_MAJOR_UPGRADE".
When there is a minor upgrade at that time IS_MINOR_UPGRADE will set to 1. And same for Major upgrade.
So using these properties, I can recognize the Upgrade mode.
Any time you change the package code but not the product code you are talking about a Minor Upgrade or possibly a Small Update if you don't change the ProductVersion. Either way, the only way to create a custom message like you ask is to write your own setup.exe / update.exe bootstrapper to detect the update scenario and display your confirmation UI.
There's nothing built into MSI or IS that allows you to easily change this.

Install Shield- Merge module dependency issues. Dll is not registering

My Issue:
I have created two merge modules. Lets call them A and B. Merge Module B is dependent on A. A installs aaa.dll to windows side-by-side. B contains bbb.dll which registers during installation and is dependent on aaa.dll. As a side note merge module A was created in Install shield 2012 and merge module B was create using the visual studio 2010 wizard.
I have an install shield project which installs both merge modules. I go into Application Data->Redistributables and add B to the installation. This automatically checks off A. If I go to Organization->Setup Design and expand the feature which contains B then click B. It brings up the window with information regarding B. In there there is a Dependencies heading which correctly lists A.
I build the project and attempt to install it on a clean VM. During the installation I get an error saying bbb.dll has failed to register would I like to ignore, cancel. At this point I looked in winsxs on the machine and notice that aaa.dll does not exist in it's proper folder. Rather it exists in a winsxs\InstallTemp\ subfolder. Then if I click ignore on the error popup, the installation continues without further errors. Then after it has completed I can manually register bbb.dll just fine, and aaa.dll exists in the proper winsxs subfolder.
My question is how can I get merge module A to completely finish and place aaa.dll in the correct location so everything will install correctly?
Things I Have Tried:
I have tried making multiple features in the Install Shield project
under Organization->Setup Design. So I created 3 features. Feature 1
at the top which just contains A. Feature 2 which contains A then B.
Finally Feature 3 which contains A again. I made all 3 features
required. I was hoping this would mean the entire feature would
finish installing and place aaa.dll in the correct side-by-side
location. However, no such luck. (I created 3 features just in case
I had the order backwards or something)
I am fairly certain that the issue is that aaa.dll is just not
installed in time or in the right place. To test this I tried installing aaa.dll first using an install shield installer that just installed merge module A. Then I ran my main installer and everything worked.
Sorry for the wall of text and any improper grammar\spelling. I will post if I figure out the issue myself just in case someone else eventually runs into this problem because it is really frustrating.
Files targeting the WinSXS and GAC aren't actually installed until commit phase execution because the API that publishes them doesn't support rollback operations. This means if you are using Self Registration on a DLL that depends on the file going to the WinSxS it won't work because you have a race condition. B.DLL will try to do a LoadLibrary() on A.DLL when calling DllRegisterServer and it won't find it.
Several work arounds:
1) Don't use Self Registration. Extract the COM data at design or build time as is the best practice.
2) Deploy A.DLL to another directory such as INSTALLDIR.
3) Wrap A.DLL up into it's own MSI and wire it up to your MSI as a setup prerequiste. This will install A in it's own transaction before starting the installation of your MSI.

Resources