I've marked a component which writes a registry key with Permanent="yes" attribute. Later I removed this attribute, but component still thinks it is permanent. Uninstall log says:
Disallowing uninstallation of component: {XXXXXXXX-3955-519D-AC73-F6832147D388} since another client exists
Searching Windows Registry for that GUID gives no result. How can I clean up "Windows Installer memory"?
Documentation to Permanent attribute says
The installer registers an extra system client for the component in the Windows Installer registry settings (which basically just means that at least one product is always referencing this component)
but where this "extra system client" can be found and uninstalled?
AFAIK This can only be "un-installed" by directly deleting the entry from the registry. You will be able to find the component under HKEY_CLASSES_ROOT\Installer\Components. The component keyname is the guid re-packed. According to here the packed GUID can be worked out by following these rules:
A packed GUID can be obtained by applying a transform to a standard
GUID. This transform performs the following operations:
removes the curly braces and separating dashes from a standard GUID
writes the first three groups of hexadecimals characters in a standard GUID in reverse order
switches every two characters in the fourth and fifth group in a standard GUID
Remember to take a reg backup first just in case and also to move the installed files out of the way before trying to install the non-permanent package.
The other alternative is to give the component a new guid and just leave old one as-is.
Related
While I was searching for the answers I found that the registry entries are made during installation only. In my installer once the installation is done then there comes a dialogue box which contains one checkbox. Based upon the checkbox value I want to make the registry entry.
Please suggest.
All system modifications (such as file installation or registry modifications) should occur DURING installation. There is a REASON for that - to make installation transactional (all or nothing), and to allow clean uninstall and repair.
Suggestion: if you want to put some user setting (a-la 'user agreed to receive marketing emails'), better do it yourself (as a custom action for example). Or better yet, in your own program (do not put it in the MSI installer)
A custom action in principle can be run in any execution sequence (including UI sequence), so you will be able to run it any time (i.e. even after that dialog)
Another option is to collect data (checkbox value) BEFORE install. Then you can include it as part of normal install sequence (as registry element)
I have a WiX project in which there is a need to check for certain registry keys that should be added as part of install.
But using the RegistrySearch element, as it is scheduled with AppSearch execute sequence, I always end up getting a blank value because till AppSearch no keys are written.
Is there any way I can determine existence of Registry keys somewhere around PostInstall?
This question is somewhat similar to : this question
Why do you need a search to see if a registry from the package is installed or not? You could simply just check the state of its component. If the state say the component got installed it means the registry is on the machine, and vice versa.
Condition examples.
I have a Component in an installer Project (created with an old Installshield Version).
The Class table entry in the MSI is created correct. But when the installer runs the entry in the registry (LocalServer32) is created with a short 8.3 Name.
What can I do so that the entries in the registry are made with the full 32bit long filename?
The problem behind it:
My component tries to locate localized DLLs with the filename. But when the component is launched with the 8.3 filename the fielname returned by GetModuleFilenameis also in 8.3 format. So when it just appends DEU to the name and changes the extension to DLL to locate the localized DLLs this sometimes fails. And I can not modify this component. (I.e. CompenentName.exe tries to find CompenentNameDEU.dll)
When I register the component manually (ComponentName.exe -register) the entries are made with the full long filename and everything works perfect.
A way around your problem is to use the GetLongPathName() API to convert the path to the long version of the filename.
This should work regardless of whether the argument is a shortened 8.3 path or whether it's already a long path.
Look at the rest of the registry entries that are created. I suspect you'll find something like a LocalServer32 data item (not a key) with apparent garbage in it. If so, what happens is that the 8.3 name is not used to locate the COM server. That "garbage" contains an encoding of ProductCode and Component guid that are used with MSI APIs to locate the target file, invoking repair if necessary.
So if this is what you see, the short answer is "don't use the Class table" because it creates an MSI links to find the target, not a file path.
Using WiX 3.5, I have an MSI with instance transforms allowing me to install the software on the same machine with different product names. To do this, I have a "hard-coded" list of product id's and names in the .wxs file defined conditionally. However, I have only the single Feature-ComponentRef definition that includes both file and non-file resources.
Installation appears to work fine, but uninstalling the instances demonstrates the behaviour mentioned in these two sources:
http://msdn.microsoft.com/en-us/library/aa367797(v=VS.85).aspx
and
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Multiple-Instance-Transforms-Walkthrough-Proposed-Simple-Addition-to-WiX-to-Make-Them-Easier-td708828.html
Specifically, none of the non-file resources (in this case, registry entries) get uninstalled save the very last instance of my application. (i.e., if I uninstall in this order: instance1, instance2, and instance3 - only instance3's non-file resources are removed.
I am presuming this is related to not having unique GUID's for nonfile components (whereas this isn't an issue for file components)
So, I was wondering whether a valid approach would be to define a single .wxs file with one product id, name and one set of features, but have a custom bootstrapper generate new GUID's for the product and non-file components which then get inserted into the MSI database at runtime? i.e., Then when it comes time to uninstall or update, I would query the registry for installed instances and retrieve their GUIDs then.
This would permit instances to be created at runtime rather than hardcoded in the .wxs in advance, and to be uninstalled cleanly.
Does that make sense? Will Burn make everything better? :)
As of version v3.6.1511.0, there is now a "MultiInstance" attribute for components. This allows a guid to be generated on the fly for each instance as per Josh Rowes suggestion in his post to the WiX mailing list (see the link in the OP). I have tested and this works correctly to cause registry data to be removed when the current instance is uninstalled, and not when the LAST instance is uninstalled.
You don't need to have unique component ID's but you do need to have unique registry keys. Check out:
Authoring Multiple Instances with Instance Transforms
The article mentions:
To keep the nonfile data of each
instance isolated, the base package
should collect nonfile data into sets
of components for each instance. The
appropriate components should then be
installed based on conditional
statements that depend on the instance
identifier.
I actually don't know what they are talking about there. I created n-Tier multiple instance installers where all the files were isolated by unique INSTALLDIR ( type 51 custom action at runtime to mutate the destination based on the InstanceID ) and all the registry data was mutated using the InstanceID as part of the path as mentioned in the article. I supported up to Sixteen unique instances with unique configuration data and unique version #'s ( each instance could be serviced via major upgrade apart from the other instances. ) All of this was to support a SaaS deployment model for an nTier application and I never ever had to create components with unique GUIDS and/or Conditional expressions.
The only thing wonky I had to do was on the client side they wanted a Shortcut on the desktop. (The Client supported multiple instances also because a site might have v1.0 in Production and v1.1 in Test )
Because I couldn't mutate the folder name (fixed) and because MSI's ShortCut table doesn't support formattable, I had to write a custom action to author the ShortCut dynamically at install table using the InstanceID into a TEMP table and then MSI created the shortcut for me.
I'm installing an Active X control that contains some COM servers. I'm using InstallShield's COM Extract at Build option to generate the registry information. This results in a lot of entries in the Registry and Class tables. (The extracted information is pretty much the same using Wix).
It appears that my COM Sever is correctly being installed except for an additional value called "InprocServer32" in the InprocServer32 key that looks like this:
HKCR\CLSID\{MY-COM-GUID}\InprocServer32
(Default) = C:\Path-to-my\file.ocx
InprocServer32 = 8tYCAGak)9S9&~swl.$?MyFeatureName>*&N$B'fk?As1x2J653?'
The only think I can make out from the extra value is the MyFeatureName which is the internal name of the MSI feature that contains the .ocx file. The key is not listed in the Registry table so it must be generated by the Class table.
The problem I'm having only happens in Windows Server 2008. It seems that the app trying to use the COM server is failing to find the path to the .ocx file from the (Default) value and instead it is finding the InprocServer32 value. This results in the app launching the MSI and then having the MSI being stuck in what seems like an infinte loop.
I'm wondering if this is a known issue in Windows Server 2008 or whether there is a way to prevent that extra value from being generated by msiexec.
I'd read this article and see if it helps you get where you want to be:
RobMen's Recommendation: Do not advertise COM information in MSI
You might want to turn off InstallShield's COM Extract at Build and instead do a One-Time COM Extract on the component in question. Then you can go into the Component Advanced section and manually manipulate the registry / com table information to be how you want it to be.
If you use WiX at all, another workflow / trick is to use Heat to build an MSI or MSM around your COM server. Then use InstallShield to edit the MSI/MSM in direct mode and the Registry view to export the Registry Keys/Values to a .REG file. Then import that .REG file into your Component in your real install project.
I can't help you diagnose what's going on, I'll just mumble a bit about what this all means. This is a counter-measure against DLL Hell. It is supposed to protect your application against some kind of other install program that could overwrite your COM server registry keys. Specifically the (Default) key which gives the location to your server DLL.
From the fake InprocServer32 value, the app can auto-detect that the Default key was overwritten and automatically launch MSI again to repair the damage. Which is what you see happening.
I thoroughly dislike the feature, it is just one more fail point in something that is already hard to troubleshoot when it blows up. And it is a useless feature, it assumes that the other installer doesn't use the exact same counter-measure. Which would have worked 10 years ago.
No idea what you'd do to troubleshoot this particular failure. Other then just punt this cr*p and let the servers just SelfReg themselves. At least you'll have something to work with when that doesn't work.