I am having installer with version 1.2.3.4, which is hardcoded in wxs file as below:
<Product Id="B91BEF19-0975-DB9185E716FC" Name="Installer" Language="1033" Version="1.2.3.4" Manufacturer="XX" UpgradeCode="c2a8ba27-bb8-186cbcd4d743">
Now i need to change the version like "1.2.3.4_temp".i.e, assigning the string to version.
As we know version attribute takes x.x.x.x and x as integer.
Is any way to get the version as 1.2.3.4_temp?
Is any way to assign ProductName (as xxxx) to version in wxs file?
You need to use product version as a numeric value.
Though Wix toolset documentation says Version attribute as The product's version string, you need to look up at the Windows Installer documentation for details about Version attribute.
It says for ProductVersion : "String format of the product version as a numeric value. (Required)"
For details about ProductVersion, please go to this link.
Related
I am facing issue for RegistrySearch for multistring, where as string search working fine.
Checked in installation logs
Action start 13:40:07: AppSearch. MSI (s) (40:E0) [13:40:07:381]:
PROPERTY CHANGE: Adding MYKEY property. Its value is ''. MSI (s)
(40:E0) [13:40:07:381]: PROPERTY CHANGE: Adding MYSERVICE property.
Its value is 'myvalue2'.
I have trimmed some logs here
Action ended 13:40:51:
ScheduleReboot. Return value 1. Action ended 13:40:51: INSTALL. Return
value 1. You must restart your system for the configuration changes
made to XXXXX to take effect. Click Yes to restart now or No if you
plan to manually restart later. Property(S): UpgradeCode =
{XXXXXX-XXXX-XXX-XXXX-XXXXXXXX}
Property(S): MYKEY = [~]myvalue1[~] Property(S): MYSERVICE = myvalue2
At end of installation it seems it has correctly evaluated the MYKEY but not during AppSearch, resulting in failing my Condition evaluation
<Feature Id="MyFeature" Level="" Display="" Title="" Description="" AllowAdvertise="no" ConfigurableDirectory="INSTALLDIR">
<MergeRef Id="MyFeature" Primary="yes"/>
<Condition Level="0">((MsiNTProductType=1) OR
(MYKEY="[~]MyValue[~]") OR
(MYSERVICE="MyService" AND MYKEY=""))</Condition>
</Condition>
</Feature>
<Property Id="MYKEY" Secure="yes">
<RegistrySearch Id="MyKey"
Root="HKLM"
Key="SYSTEM\CurrentControlSet\Services\MyService"
Name="mykey"
Type="raw" />
</Property>
<Property Id="MYSERVICE" Secure="yes">
<RegistrySearch Id="MYSERVICE"
Root="HKLM"
Key="SYSTEM\CurrentControlSet\Services\MyService"
Name="DisplayName"
Type="raw" />
</Property>
UPDATE: I might have missed you stating it already, but when checking whether the property set by the AppSearch search has any assigned value at all using simply PROPERTYNAME as condition, the condition shows up as true - meaning that "something" exists in the property in question, the text is just not displayed.
Is it sufficient to test just for the presence of a value, or do you need to check the specific value of MYKEY? If the mere presence of a value is enough, then you may be able to use this condition:
((MsiNTProductType=1) OR (MYKEY) OR (MYSERVICE="MyService" AND MYKEY=""))
I guess this answer from Rob Mensching from the WiX-users mailing list answers the question with certainty. Multi-string is simply not supported for AppSearch.
There is no need to doubt the accuracy of this since Rob was on the original MSI team. You need to abandon this approach. Sorry to say. Unless the above workaround that I just added could work (check not the value, but if there is a value at all being retrieved from the registry).
A couple of other, potential workarounds:
You could read the multi-string from a custom action. I just verified that it works with a test VBScript - the forbidden MSI tool :-).
Could you search for a file or directory on disk that would signify the same thing you retrieve from the registry with this multi string?
As my motto goes every now and then: let's obsess over this (as opposed to: "careful, we don't want to learn from this" - which is another motto of mine - which tends to be the better option).
It is truly odd, that I can replicate what you state about your log file. I see a CommandLine entry which shows the multi-sting correctly, albeit with several extra null characters (slightly shortened log entry):
CommandLine: NORMALSTRING="sample regular string" MULTISTRING="[~~~]String 1[~~~]String 2[~~~]String 3[~~~]" INSTALLFOLDER="C:\Program Files (x86)\WiX3_GenericTestProject\" TARGETDIR="C:\" ACTION="INSTALL" EXECUTEACTION="INSTALL" ROOTDRIVE="C:\" INSTALLLEVEL="1" SECONDSEQUENCE="1" ADDLOCAL=Empty,Modules,ProductFeature
and also, later in the log file, after InstallFinalize:
Property(S): MULTISTRING = [~]String 1[~]String 2[~]String 3[~]
I really don't understand how that comes about. Somehow the AppSearch must have really set the property in question even if it didn't look like it did - the property just can't be retrieved correctly (or formatted correctly), and hence doesn't work in (feature) conditions either?
Maybe the underlying data model in Windows Installer has stored the retrieved registry multi string value as a BSTR (the abomination of a COM string format which allows embedded nulls and can be compiled and linked without being properly allocated / constructed via SysAllocateString - "burnt child, smells burnt - and all that...").
Anyway, I suppose AppSearch expectes a regular, null-terminated string buffer and interprets the BSTR as such? Hence stumbling on the first null value which is the first character of the data string section of the BSTR (not the length prefix section - the BSTR pointer points 4 bytes into the allocated BSTR memory) and reports an empty string overall? The property values that show up in the log file must have been read directly from the underlying data model by other means? I would assume the MSI Win32 C++ functions? But wouldn't that also be the case for AppSearch? Something is wrong with how this property string - with embedded nulls - is being displayed and used in conditions.
So in summary: maybe the retrieval of the multi string actually works, but the exposed value via Session.Property("PROP") erroneously reads the potential, native BSTR as a null-terminated string buffer and interprets the leading null as the end of the string buffer? Sort of doesn't make sense considering Session.Property is a COM call and should definitely understand a BSTR? Theories like these are never correct, but maybe they can help create some new ideas at least. What seemed like a missing Windows Installer feature, sort of smells like a bug I think. Or as it is in the real world: a technical problem, not easily fixed and hence seen and accepted as a missing feature.
Let me link together your questions on this issue for reference (and a couple of other answers):
RegistryValue Element of type multiString.
Failing condition wix.
Passing multiString values to installer through command-line.
I have a Visual Studio bundle file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle
Name="Some Name"
Version="3.2.2"
Manufacturer="Some Company"
Copyright="Copyright: Some Company, Inc">
...
</Bundle>
</Wix>
After build exe details menu contains two parameters (File description and Product Name) and these parameters have the same value. There is a way make these values different using only WIX functionality?
As of Wix Version 3.10.2, you cannot set different values for the ProductName and FileDescription fields of the exe file description resource.
Looking at the WIX source code, specifically the file src\tools\wix\Binder.cs from WIX310-Debug.zip downloadable from here, shows the following code fragment for setting the exe file's resources:
Microsoft.Deployment.Resources.VersionStringTable strings = version[1033];
strings["LegalCopyright"] = bundleInfo.Copyright;
strings["OriginalFilename"] = Path.GetFileName(outputPath);
strings["FileVersion"] = bundleInfo.Version; // string versions do not have to be four parts.
strings["ProductVersion"] = bundleInfo.Version; // string versions do not have to be four parts.
if (!String.IsNullOrEmpty(bundleInfo.Name))
{
strings["ProductName"] = bundleInfo.Name;
strings["FileDescription"] = bundleInfo.Name;
}
Notice that ProductName and FileDescription are set to the same value.
If this is important you could request a new feature via the WiX issue tracking database: https://github.com/wixtoolset/issues/issues.
I can define a product version variable like so :
<?define ProductVersion="!(bind.FileVersion.ServiceExeFile)" ?>
which I can reference inside string parameters like this :
$(var.ProductVersion)
..but it is displayed as literal text if I use it in my InstanceTransforms productName parameter.
Can anyone suggest how I might work around this?
I have installation of version 1.1. I created upgrade with version 1.2.
In both products I have 2 files:
<Component Win64="yes" Id="cmpFILE1" Guid="*">
<File Id="filFILE1" KeyPath="yes" Source="$(var.BasePathCMP)\Performance.dll" />
</Component>
<Component Win64="yes" Id="cmpFILE2" Guid="*">
<File Id="filFILE2" KeyPath="yes" Source="$(var.BasePathCMP)\LockLib.dll" />
</Component>
During the upgrade LockLib.dll is removed and not being replaced.
In clean installation of 1.2 it is present.
What can cause that behavior?
One of the reasons why this happens is because the action RemoveExistingProducts is being executed after the installation package performed the upgrade. In this case, the MSI detects the file is the same as in previous version and then removes it. You could:
Change order of RemoveExistingProducts
Set the DLL to Shared
I'd recommend option one.
RemoveExistingProducts Element
I'm thinking you changed the component guid for a file that is in both MSIs, older and upgrade. When the RemoveExistingProducts is towards the end of the install the upgrade behaves like a merge, overwriting files if necessary and incrementing ref counts for shared component guids. At the end the REP is removing the old product and decrementing ref counts for the component guids. If there are no more clients for the guid it will be removed. If the guid of a "shared" file changed it will have no more clients and be removed. The thing about an REP at the end is that you must follow component sharing rules, but you don't if you sequence REP at the start of the upgrade.
I'm adding an example for future reference.
Say the first install has 3 files A, B, C, and three guids that are 1, 2 and 3. Your upgrade has the same three files but the guids are 1, 2 and 8. When REP is at the end the upgrade installs over the old product first. Guids 1 and 2 get their ref counts incremented from 1 to 2. Guid 3 stays at 1. Then the older product is uninstalled. Guids 1 and 2 get ref counted down to 1, they are still in use so the files attached to the component guids stay. Guid 3 goes down to zero, has no ref counts so the component is removed, but it's attached to file C so C gets removed even though you just installed it.
We can get the productversion in wix using !(bind.fileVersion.Product.exe). This returns the version as 3.8.2363.0. How can I get the version up to build version, i.e. 3.8.2363.
I followed Binding WIX FileVersion sub values? this link, but using
"!(bind.property.ProductVersion.Major)" do not solve my problem.
<?define ProductVersion123="!(bind.fileVersion.mainexe_dll)" ?>
<Product Id="{7BDF78BF-95E8-4ABB-8A0F-4A1483D7FDD1}" Name="SpreadsheetConverter !(bind.property.ProductVersion123.Major)" Language="1033" Version="!(bind.property.ProductVersion123.Major)" Manufacturer="ABC" UpgradeCode="$(var.ProductUpgradeCode)" Codepage="1252">
This gives error:
Unresolved bind-time variable Mainexe !(bind.property.ProductVersion123.Major).
Please Help.
Thanks
You have to realize what !(bind.property.X) does. It retrieves the value of the X property from the MSI's Property table. You have not setup a ProductVersion123 property in the MSI, you have created a WiX preprocessor variable ProductVersion123.
So what you have to do is assign the Product's Version attribute to $(var.ProductVersion123) (which sets the ProductVersion property of the MSI). Now you can access that with !(bind.property.ProductVersion), including the !(bind.property.ProductVersion.X) extensions.