WiX 3: Error 1406: Could not write value {ValueName} to key {KeyName} - wix

I recently converted an old WiX 2 project to WiX 3. In the previous WiX project there was a component that contained a number of shortcuts, as follows.
<Component Id="ShortcutsComponent" Guid="$(var.ShortcutsComponentGuid)">
<Shortcut Id="Shortcut1" Name="Shortcut1Name" LongName="Shortcut1LongName"
Directory="ShortcutsDir" Target="{Target}" />
<Shortcut Id="Shortcut2" Name="Shortcut2Name" LongName="Shortcut2LongName"
Directory="ShortcutsDir" Target="{Target}" />
</Component>
When I converted the project to WiX 3 this caused the following error.
error LGHT0204 : ICE43: Component ShortcutsComponent has non-advertised shortcuts. It's KeyPath registry key should fall under HKCU.
To resolve the error I made modified the ShortcutsComponent by adding a RegistryValue element as follows.
From our Variables.wxi file.
<?define JAWSVersion = "$(env.Major).0"?>
<?define FSRegistryKey = "SOFTWARE\Freedom Scientific"?>
<?define JAWSRegistryKey = "$(var.FSRegistryKey)\JAWS"?>
And in the WXS file, which includes Variables.wxi, I added the following line to ShortcutsComponent.
<RegistryValue
Root="HKCU" Key="$(var.JAWSRegistryKey)\$(var.JAWSVersion)\Components"
Name="ShortcutsComponent" Action="write" Type="integer" Value="1"
KeyPath="yes" />
I made similar changes to a number of components.
Now I am getting errors when installing the software, but only on some computers. The error is as follows.
Error 1406: Could not write value {ValueName} to key {KeyName}.
System error. Verify that you have sufficient access to that key,
or contact your support personnel.
I considered replacing the above RegistryValue line with something like the following but I do not expect the results to be any different.
<RegistryKey Root="HKCU" Key="$(var.FSRegistryKey)" Action="create">
<RegistryKey Key="JAWS" Action="create">
<RegistryKey Key="$(var.JAWSVersion)" Action="create">
<RegistryKey Key="Components" Action="create">
<RegistryValue
Name="ShortcutsComponent" Action="write"
Type="integer" Value="1" KeyPath="yes" />
</RegistryKey>
</RegistryKey>
</RegistryKey>
</RegistryKey>
Does anyone have any suggestions on how to solve this problem?
NOTE: I was asked to give the precise values for {ValueName} and {KeyName}. Here are the relevant lines from the log file.
MSI (s) (1C:8C) [14:36:29:183]: Executing op: RegOpenKey(Root=-2147483647,Key=SOFTWARE\Freedom Scientific\JAWS\17.0\Components,,BinaryType=1,,)
MSI (s) (1C:8C) [14:36:29:183]: Executing op: RegAddValue(Name=RemoveExploreDir,Value=#1,)
WriteRegistryValues: Key: \SOFTWARE\Freedom Scientific\JAWS\17.0\Components, Name: RemoveExploreDir, Value: #1
MSI (s) (1C:8C) [14:36:29:183]: Note: 1: 1401 2: HKEY_CURRENT_USER\SOFTWARE\Freedom Scientific\JAWS\17.0\Components 3: 1021
Error 1406. Could not write value RemoveExploreDir to key \SOFTWARE\Freedom Scientific\JAWS\17.0\Components. System error . Verify that you have sufficient access to that key, or contact your support personnel.
MSI (s) (1C:8C) [14:40:09:789]: Product: Freedom Scientific JAWS 17.0 -- Error 1406. Could not write value RemoveExploreDir to key \SOFTWARE\Freedom Scientific\JAWS\17.0\Components. System error . Verify that you have sufficient access to that key, or contact your support personnel.
I hope this helps.

This is more of a report of a discovery than an answer. As it turns out the problem was not in the WiX code but in a custom action contained in a DLL that is used by the installer. This custom action created the registry key "HKEY_CURRENT_USER\Software\Freedom Scientific\RJSetup" with the REG_OPTION_VOLATILE option. What this means is that if the "HKEY_CURRENT_USER\Software\Freedom Scientific" did not already exist, it too was created with the REG_OPTION_VOLATILE option. When the WiX installer attempted to write to any key under "HKEY_CURRENT_USER\Software\Freedom Scientific" this caused the Error 1406. We are fixing the custom action so that it first creates the "HKEY_CURRENT_USER\Software\Freedom Scientific" registry key as a standard key and then creates the "HKEY_CURRENT_USER\Software\Freedom Scientific\RJSetup" registry key with the REG_OPTION_VOLATILE option. That hopefully will fix the problem.
The moral of the story is, if you find an odd error in a WiX installer that you cannot figure out in code that appears to be consistent with thousands of resources found online consider the possibility that you are shooting yourself in the foot in one of your custom actions.

Related

Wix set program run as admistrator

I have already set the program run as the windows startup, however the program can only work when it is run as administrator in windows 10, can anybody tell me what I should add in the code to set that? Here is my Wix code:
In product modules there is
<ComponentRef Id="RegistryEntries"/>
and then
<Fragment>
<DirectoryRef Id="ProgramFilesFolder">
<Component Id="RegistryEntries" Guid="14fe9526-0da4-4761-ad27-8a77f145c6b5">
<RegistryKey Root="HKCU"
Key="Software\Microsoft\Windows\CurrentVersion\Run"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="March Networks Video Assistant" Value="[INSTALLFOLDER]March Networks Video Assistant.exe" KeyPath="yes"/>
</RegistryKey>
</Component>
</DirectoryRef>
</Fragment>
Thank you so much to everybody.
The problem is you are putting this registry key in the HKCU which will run things in the current user's context at startup.
If you want it to be run as administrator on startup it needs to go into HKLM.
Try the following:
<Fragment>
<DirectoryRef Id="ProgramFilesFolder">
<Component Id="RegistryEntries" Guid="14fe9526-0da4-4761-ad27-8a77f145c6b5">
<RegistryKey Root="HKLM"
Key="Software\Microsoft\Windows\CurrentVersion\Run"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="March Networks Video Assistant" Value=""[INSTALLFOLDER]March Networks Video Assistant.exe"" KeyPath="yes"/>
</RegistryKey>
</Component>
</DirectoryRef>
</Fragment>
So notice I changed HKCU to HKLM (this might cause ICE warnings during compilation but you can safely ignore them). If you are using a per user install, I don't know if this will be able to write the registry key though unless the install is run as administrator... Also I put " around your RegistryValue's value since it's always nice to wrap full paths in quotes because of spaces.
Another nice thing you can do is update the RegistryValue's value using the install path of the component which can be referenced using the following syntax:
[#IDOfFile]
So if your component defining the "March Networks Video Assistant.exe" <File> uses Id="MarchNetworksVideoAssistant.exe" you can update your RegistryValue's value to
value=""[#MarchNetworksVideoAssistant.exe]""
You can get a good explanation of this syntax here
If a substring of the form [#filekey] is found, it is replaced by the full path of the file, with the value filekey used as a key into the File table. The value of [#filekey] remains blank and is not replaced by a path until the installer runs the CostInitialize action, FileCost action, and CostFinalize action. The value of [#filekey] depends upon the installation state of the component to which the file belongs. If the component is run from the source, the value is the path to the source location of the file. If the component is run locally, the value is the path to the target location of the file after installation. If the component has an action state of absent, the installed state of the component is used to determine the [#filekey] value. If the installed state of the component is also absent or null, [#filekey] resolves to an empty string, otherwise it resolves to the value based upon the component's installed state. For more information about checking the installation state of components, see Checking the Installation of Features, Components, Files.

Wix - How to get user input from a previously installed msi?

I'm trying to do an installer using wix 3.8. I can use custom properties to store my own input, but I'd like to use values that where inputs on a previously installed msi.
Is there a way to accomplish such thing?.
To get you in the right direction add this (of course adapt it to your needs first) in your fist MSI:
<DirectoryRef Id="INSTALLDIR">
<Component Id="RegistryEntries" Guid="{0AC76129-F8E2-47D3-B9FD-09B1E10A8541}">
<RegistryKey Root="HKLM" Key="Software\Company123\App123" Action="create">
<RegistryValue Type="integer" Name="SomeIntegerValue" Value="1" KeyPath="yes"/>
<RegistryValue Type="string" Name="UserInput" Value="[USERINPUT]" />
</RegistryKey>
</Component>
</DirectoryRef>
Don't forget reference the component in your <Feature> <ComponentRef Id="RegistryEntries" />
When you install assign a value to the property [USERINPUT] e.g. msiexec /i your.msi /qb+ USERINPUT="the value to be saved in registry"
Then in the second MSI add something like this:
<Property Id="READREGISTRY">
<RegistrySearch Id="USERINPUT_Value" Root="HKLM" Key="Software\Company123\App123" Name="UserInput" Type="raw" />
</Property>
The value/string you entered during installation USERINPUT= will be stored in your second MSI in the property READREGISTRY
Here a piece of log in my second msi:
PROPERTY CHANGE: Adding READREGISTRY property. Its value is 'testing registry wef wef wef w'.
Based on your installation where it might be Per User or Per Machine you may adjust the Root to HKCU for PerUser installs or leave it to HKLM for PerMachine.
For more information please refer to Wix documentation, hints: "How To: Write a Registry Entry During Installation" and "How To: Read a Registry Entry During Installation".
Generally, no. There is no requirement for a Windows Installer package to record the input it takes from the user. Some do record some information in the registry and you might choose to rely on finding it there.
As an alternative, you might find that the other installer can be run without a UI and can be sufficiently controlled with properties passed into it. If so, you can write your own UI (one way would be a custom WiX Bootrapper Application [example]) to gather the inputs before running the installer.
Create a custom action within the MSI which gets installed first, then either write the values/user entries that you want into a file or registry. Within your final MSI read the values from registry/file and use it.
Here is an example of how you can read a value from the user and update the your app.config, this is not an apple to apple scenario, but this will guide you through it.
http://bensnose.blogspot.com/2013/03/more-custom-actions-with-wix.html
Disclaimer: I havent tried out what is mentioned in this blog post, but I have done things very similar and found that it has good explanation, thats why I posted the link to it.

How to run .reg files when running the msi?

I am trying to understand how my setup.msi inserts registry values when installing it. In Orca editor I am seeing like this,
After installing the msi, in the log file I am seeing like this,
MSI (s) (A8:B4) [16:27:28:674]: Executing op: ComponentRegister(ComponentId={45667B7F-9DC7-43B7-BE9E-3215ED1B1985},KeyPath=02:\SOFTWARE\myCompany\MySolution\Plugins\MyProduct\ProductCode,State=3,,Disk=1,SharedDllRefCount=0,BinaryType=0)
I want to do the reverse engineering of this mechanism, can any one help me to understand this? I want to recreate the same using WIX, so I just tried like below
<Component Id="RegistryEntries" Guid="*">
<RegistryKey Root="HKLM"
Key="Software\Microsoft\MyCompany"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="MyApp" Value="[INSTALLLOCATION]" KeyPath="yes"/>
<RegistryValue Type="string" Name="Configuration Files" Value="[INSTALLLOCATIONCONFIG]"/>
<RegistryValue Type="string" Name="Configuration Files1" Value="[INSTALLLOCATIONCONFIG1]"/>
</RegistryKey>
</Component>
When I built the msi and if edit it Orca, I am seeing like below,
What should I do to get the msi as shown in the previous image?
MSI expresses registry data in the Registry table. During the installation, the system determines which features and components are being installed therefore which registry adds, updates and deletes to perform. The actual work is carried out by the WriteRegistryValues and RemoveRegistryValues actions.
It is not a best practice to "execute a reg file" during an installation because it's out of process and MSI can't manage the changes. Instead use the WiX Heat tool to harvest the contents of the registry file into wix xml source for inclusion in your installer.

Failed to create registry entry using WiX

The following code failed to create registry entry on Windows 7.
<Component Id='RegistryEntry1' Guid='1BECF977-A7A1-448E-8EC8-843A10E7F6D7' Directory='TARGETDIR'>
<RegistryKey Root='HKLM'
Key="SOFTWARE\Microsoft\Microsoft SDKs\Silverlight\v5.0\AssemblyFoldersEx\SimpleMvvmToolkit_2012.SL"
ForceCreateOnInstall="yes"
ForceDeleteOnUninstall="yes">
<RegistryValue Type="string"
Value="C:\Program Files\SimpleMvvmToolkit_2012\Binaries\Silverlight\v5.0\"
KeyPath="yes"/>
</RegistryKey>
</Component>
What could be the problem?
If the registry key wasn't created, more likely than not, the Component was not installed. Check a verbose log file from the install, for example:
msiexec /i path\to\your.msi /l*v install.txt
In that log file you will see lines like:
Component: RegistryEntry1; Installed: Absent; Request: Local; Action: Local
I expect the Action will be None or something not Local. Then look up in the log file to see why the Component was not installed.
PS: The ForceCreateOnInstall and ForceCreateOnUninstall are not necessary unless you expect random values to be created under that registry key that you must remove on uninstall.

WiX: Error RegistryKey element contains an unexpected attribute 'ForceDeleteOnUninstall'

I'm new to WiX. I just installed WixW 3.7 in order to build an open source JiraSVN plugin. But the build breaks in Visual Studio with the following errors:
The RegistryKey element contains an unexpected attribute 'ForceDeleteOnUninstall'.
The RegistryKey element contains an unexpected attribute 'ForceCreateOnInstall'.
These errors reference the product.wxs file, which contains the following elements:
<Component Id="C__Registry" Guid="{40D60013-...D30D5}" Win64="yes">
<RegistryKey Root="HKCR" Key="CLSID\{CF732FD7-...1A7E9D}" ForceDeleteOnUninstall="yes">
<RegistryValue Value="TortoiseSVN Jira Plugin" Type="string" Action="write" />
<RegistryKey Key="Implemented Categories">
<RegistryKey Key="{3494FA92-...5E7831}" ForceCreateOnInstall="yes" /> </RegistryKey>
</RegistryKey>
</Component>
I am also getting warnings such as:
The 'ForceDeleteOnUninstall' attribute is not declared.
The 'ForceCreateOnInstall' attribute is not declared.
From what I can find in the WiX documentation, these are standard attributes in the WiX framework. So what could be causing them to be unrecognized? Where should they be declared?
First, why are you adding those attributes? From the snippet you sent they are unnecessary and just going to bloat your install. No need to force anything there.
Second, you must have WiX v3.5 or less installed on your Visual Studio machine. Those attributes were added in WiX v3.6.