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.
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 custom bootstrapper that allows the user to uninstall components of the installation or the entire installation. In either situation, the bootstrapper is removed and no longer available in 'Programs and Features'. Is there a way I can prevent the bundle from being removed if I know the user is just uninstalling a component of the installation?
I thought maybe I could set the installation state to modify but I don't see a way to do that.
During the Plan phase, you need to handle a handful of events to set the State you want for each MsiFeature and Package within your bundle.
For each wix msifeature and/or package the user is changing, you'll need to set the State value of the event args to AddLocal or Remove for features, and Present or Absent for packages during the planning phase event handlers (BootstrapperApplication.PlanPackageBegin and BootstrapperApplication.PlanMsiFeature). For any remaining unchanged, set the state to None.
Then, when you call Engine.Plan(...), you'll need to provide a LaunchAction value of Modify or Install if you want the bootstrapper to exist after the run, or Uninstall if you want to have the bootstrapper removed. I suspect this is where you're having issues -- check what value you're passing to Plan()
I wrote a series of blog posts you may find helpful (particularly part 5): Writing Your Own .NET-based Installer with WiX
When I execute my MSI with UAC ON the UAC is not prompted for some time. I am trying to read some registry entry in a custom action before "CostFinalize". My Registry read function will consider a default value if registry entry is not found. But in my case the registry entry is there but it fails to read because the key doesn't have read permission for "User". Although Admin have full permission.
Registry read seems to be happening before UAC prompt. How can i make sure UAC is prompted at start only so that registry read can be successful.
Issue explanation
We have an old installer written in WIX. Where we are writing a registry entry for install location something like this
HKLM\Software\CompanyName\Product\Install\CompInstallDir = [InstallDir]\Product\Component.
This registry entry does have permission for Admin only even user doesnt have read permission I dont know why (i didnt write that code). there are some other entries under HKLM\Software\CompanyName\Product\Install
Now I have to make changes in the installer code for upgrade. In which i have to read this install location i.e., [InstallDir]Product\Component and trim it to [InstallDir]. So I already have an existing custom action (from previous installer code only) which reads the registry and sets Property INSTALLDIR, also some other properties and do backup of some config files. This custom action is under "InstallExecuteSequence" which as per my understanding should prompt for UAC if required. This custom action is called before "CostFinalize".
The thing which should have been there in old installer is Writing a registry entry containing only [InstallDir] which wasn't in place. Due to which that custom action is in place which is not a good way of doing, but being legacy code have to maintain it :(
Hope I am able to explain my problem :)
In this SO thread I explain how UAC prompts are triggered.. Basically, you need a bootstrapper, and in its manifest set the execution level accordingly.
Regarding the custom action to read the registry. Why don't you use the built in support from Windows Installer to make a registry search, using AppSearch and RegLocator tables? As a general rule, its not recommended to reinvent the wheel. A default value for the search can be specified by simply defining the property (name of the search) in Property table.
The normal best practice is for the Install UI sequence to run as standard user and for the Install Execute sequence to elevate if the MSI is built to require it. ( For example a per-user install writing to per-user locations might not ever need elevation ).
The other best practice is to use AppSearch to read registry values into properties. The AppSearch also runs in the InstallUI sequence so normally the expectation is that these reads can be performed using standard user permissions.
In your case, you require admin to do the read. In all my years writing hundreds of installers I've never had that requirement. To give you better advice I'd have to ask what is the nature of this registry value and why is it only readable by administrators? After you read it, what do you intend to do with it?
Options include a bootstrapper to elevate the entire installer including UI sequence but that's usually not advised. Otherwise you need a deferred custom action running without impersonation (SYSTEM context) to do the read but at that point you can't set a property so you'd have to use the registry value right there for whatever purpose is intended.
Very strange requirement... I'm detecting a code smell.
I am making an installer, which need read a registry key and get a value, then use this value to access another registry then get the INSTALL dir.
Any condition mentioned above will stop the installation if fails.
How to set such conditions that one is dependent on the other?
Thanks.
Use RegistrySearch then a Condition element in the Product element using the Property from the result of the RegistrySearch.
The installer I'm writing using WiX 3.0 uses a RegistryValue element to modify an existing registry value (originally written by our main product). I'm trying to figure out a way to restore the registry value when the user uninstalls my utility. I'd like to avoid using a custom action, but that might be the only recourse? TIA.
I did this. The registry value in question was the application associated to a file extension, but it could be any registry value.
My first idea was to use a "custom action" for install and uninstall to preserve
and restore, respectively, the associated regy state. This
seemed simple enough.
I created a setup project in VS2008 and built the CA's as javascript files. The "on install" script grabbed the existing regy value and stashed it into a well-known place. The "on uninstall" script would look in the well-known place, and then put the value found there, back in the original location.
Easy, right?
There were two problems:
the script that ran during install, to preserve the pre-existing registry value,
runs AFTER the registry has already been updated
with the values for the newly installed thing. So it preserved the new setting instead of the setting that was there before the MSI ran. Not useful.
The script that runs during uninstall, runs AFTER the registry values, and in fact the entire directory subtree,
have been deleted. Including the stashed value. So it had lost its state.
To solve that I wrote another script that
re-orders the custom actions so they run at the proper times.
There's actually one more twist. Obviously, the "Restore" script (on
uninstall) won't work if it is run after the registry entries for the app have been deleted. I can't remember now, why... but I also determined that this script could not run before that. Somehow that wasn't working either.
So, I modified the MSI to run the restore script
twice. In phase 1, it transfers the stashed value to a "parking lot" in the registry.
Then the application's Keys and Values in the registry get deleted, but the parking lot remains. In
phase 2, outside the transactional protection, the restore script retrieves the state from the parking lot, restores
the file association, and then deletes the parking lot.
I can't remember exactly why I needed to do this in 2 steps, but I remember fighting with it for a while before coming up with that solution.
The way it works in development:
set the on install and on uninstall CA's in the VS project
build the VS Setup project
run the post-processing script that modifies the MSI.
When using the MSI, it's a little more complicated than I originally thought but it works.
If you are using WiX, you may have more control over the time and ordering of the steps, so may not need that post-processing step.
Finally, you said you wanted to avoid a CA. To me, CA's are avoided because they are painful to produce in C++, and producing them in .NET is often inappropriate. But, it's pretty simple to use Javascript for CA's. Some people think script is the wrong tool for the CA job. I think that's wrongheaded. I think script is a very good tool for this purpose. And once you can accept script as a good tool, then you don't need to hold your nose about creating a custom CA.
The registry table is incapable of writing a registry value during an uninstall so it is correct that this must be done via custom action. I am of the opinion that using script is bad. Whether you choose to listen is up to you. I can tell you that just the other day I was called into to trouble shoot a situation where some wrote a vbscript CA that was failing because the file system object had been unregistered as part of a security lockdown process.
I suggest C++ or C#/DTF depending on your needs.
Faced with similar issue, need to update the registry value on install and restore to previous value on uninstall.
Is the only solution possible is creating a custom action for this purpose?
I found a extension for wix that has fucntions for this purpose
link to wix extensions