wix unable to use string in detect condition - wix

I am using WIX installer to genrate exe, till now everything is working fine but now i need to add one detect condition in exe package as given below.
<ExePackage
Id="AccessRuntime2013"
DetectCondition="((MsAccessInstalled = Outlook.Application.15) AND (MSOffice2013RuntimeInstalled = 0))" >
MsAccessInstalled is a variable which stores version of outlook installed and MSOffice2013RuntimeInstalled is a variable which checks whether access runtime is installed or not. Both variables are setting properly.
I have to run this exe only when MsAccessInstalled = "Outlook.Application.15" and MSOffice2013RuntimeInstalled is not installed. If i run both condition separate then it works but if i clubbed both it doesn't works. It gives error message as Failed to parse condition "((MsAccessInstalled = Outlook.Application.15) AND (MSOffice2013RuntimeInstalled = 0))". Unexpected character at position. Please help.

What happens when you change the DetectCondition to
<ExePackage
Id="AccessRuntime2013"
DetectCondition="MsAccessInstalled ~= "Outlook.Application.15" AND MSOffice2013RuntimeInstalled = 0"
... />
You can also test your conditions by making some test util:Condition tags in your bootstrapper.
<util:Condition Message="MSAccessInstalled condition failed">MsAccessInstalled ~= "Outlook.Application.15"</Condition>
<util:Condition Message="MSOffice2013RuntimeInstalled condition failed">MSOffice2013RuntimeInstalled = 0</Condition>
Run your bootstrapper and see if either condition fails. Do remember to remove these conditions once you're done testing as they will cause issues if put into production.

Related

WIX MSI conditions

In the Zabbix Agent MSI, there is the following line, when one opens MSI:
<Condition Message="Please enter the name or IP address in the Zabbix server IP/DNS field !">NOT (NOT (Installed OR WIX_UPGRADE_DETECTED OR WIX_DOWNGRADE_DETECTED)) OR ((NOT (Installed OR WIX_UPGRADE_DETECTED OR WIX_DOWNGRADE_DETECTED)) AND ((UILevel<5 AND SERVER) OR UILevel=5))</Condition>
Can someone explain the logic? When one rewrites the condition in a more sensible way:
NOT (
NOT (Installed OR WIX_UPGRADE_DETECTED OR WIX_DOWNGRADE_DETECTED)
) OR (
(NOT (Installed OR WIX_UPGRADE_DETECTED OR WIX_DOWNGRADE_DETECTED))
AND ((UILevel<5 AND SERVER) OR UILevel=5)
)
So if Installed=1 then the condition is satisfied due to the double NOT (which it should not be, since the message should only appear if the software is not installed and thus, there is an error in the MSI). The double NOT makes no sense.
Or is there some other interpretation of the condition above?
This is all governed by Windows Installer's Conditional Statement Syntax
https://learn.microsoft.com/en-us/windows/win32/msi/conditional-statement-syntax
It appears your trying to do custom UI work but I don't know how all of that relates to a server name IP address.
In these scenarios I have a custom action that implements business rule checks (reach out and touch a server or validate FQDN/IP ) and set a property to 1 or 0. Then I use mutually exclusive control events (Publish elements with Condition in the inner text ) to either Spawn a dialog that says there is a problem or NewDialog the next dialog of the wizard loop.

WIX condition only on Install not working

I have the following within the Product Tag:
<Property Id="LICENSEKEY" Admin="yes" Hidden="no">
<RegistrySearch Id="RememberLicenseKey" Root="HKLM" Key="SOFTWARE\MyApp\key1\Settings" Name="LICENSEKEY" Type="raw"></RegistrySearch>
</Property>
<Condition Message="License key is required to proceed">LICENSEKEY AND NOT Installed</Condition>
What I want to do is pass the License key as a command line argument to msiexec, and then set it in the registry. If the key is not passed I want to cancel the installation. Therefore, this check only needs to be run at install time. However, the condition that I have added causes a popup both at install and uninstall time. Can't seem to figure out what I am doing wrong.
EDIT:
I tested with the following condition and it seems to show the message both on install and uninstall:
<Condition Message="License key is required to proceed">NOT Installed</Condition>
The Message for a Condition element will be displayed when the condition evaluates to false, meaning the condition was not met.
This is noted in the Message attribute description in the WiX Condition documentation:
Set the value to the text to display when the condition fails and the installation must be terminated.
To resolve this issue, the logical operators in the Condition just need to be changed to LICENSEKEY OR Installed
This is a late answer, but, hopefully, this will help any future visitors that find this question.
You may need to clarify your requirement. That WiX source does a search for the key, so does it need to be passed on command line or you'll cancel the install (as your post says), or can it be used if it's found in the registry by that registry search? Currently it appears that your registry search is overwriting anything you pass on the command line, including setting it to null, so check that with a verbose log.
Also, all the launch condition examples I've seen or used have a CDATA around the text of the actual condition - that may be part of the problem.
I'll assume you allow the key on the command line or in the registry. So your registry search should be for another property name, let's call it REGKEY, so it doesn't set your passed LICENSEKEY to null. Then you have a set property (type 51) custom action immediately after the search that sets LICENSEKEY to REGKEY with a condition of -Not LICENSEKEY- so it will set LICENSEKEY to REGKEY only if LICENSEKEY was not passed on the command line. So if you pass it on the command line it will be used, otherwise the registry one will be used. At that point, a condition of LICENSEKEY should work ok as a launch condition. Internally, the AppSearch that finds the registry item is typically immediately followed by the launch condition check in a WiX MSI, so you need to set LICENSEKEY before the launch condition check.

BURN: Logging BURN_PACKAGE-> sczLogPathVariable to be used to create complete Log file

I am using WIX 3.7, and I am wanting to have my MSI and BURN log files, be created at my desired location. I tried verbatim both the approaches, mentioned in How to set or get all logs in a custom bootstrapper application newsgroup post. However, Log File gets created in the default location. Since I had time on hand, I decided to explore WIX 3.7 through WIX 3.9 Source Code, attempting to find where BURN_PACKAGE-> sczLogPathVariable data member is used.
However I found just 5 references to BURN_PACKAGE-> sczLogPathVariable
\wix38-debug\src\burn\engine\logging.cpp(191):
if ((!fRollback && pPackage->sczLogPathVariable && *pPackage->sczLogPathVariable) ||
\wix38-debug\src\burn\engine\logging.cpp(197): hr = VariableSetString(pVariables, fRollback ? pPackage->sczRollbackLogPathVariable : pPackage->sczLogPathVariable, sczLogPath, FALSE);
\wix38-debug\src\burn\engine\package.cpp(152):
hr = XmlGetAttributeEx(pixnNode, L"LogPathVariable", &pPackage->sczLogPathVariable);
\wix38-debug\src\burn\engine\package.cpp(303):
ReleaseStr(pPackage->sczLogPathVariable);
\wix38-debug\src\burn\engine\package.h(165):
LPWSTR sczLogPathVariable; // name of the variable that will be set to the log path.
I was expecting some code that would actually retrieve the value of MY VARIABLE and then CONCATENATE that value with the Log File Name that was synthesized, to create the complete file path. Maybe I am missing something obvious ? Do you guys have any suggestions ?
*Package/#LogPathVariable is used to specify a variable that gets the path to the log. To control the logging, use the Log element.

How to ensure a feature is installed during a Windows Installer AdminInstall

I am using WiX to create a moderately complex installer. I have a Level 0 Feature that I would like to install conditionally, but also always during an Admin install, to make patching through admin images easier. I've tried several things:
Setting a property before the AdminUISequence's CostFinalize action (which is when msdn claims the Condition table is evaluated). The condition in that case looks like:
<Condition Level="1">( VersionNT >= 601 AND NOT FASTINSTALL = "1" ) OR INSTALLCONDFEATURE = "1"</Condition>
where FASTINSTALL and INSTALLCONDFEATURE are both Secure and Admin.
Using the Windows Installer ACTION or EXECUTEACTION properties. In this case the condition is something like:
<Condition Level="1">( VersionNT >= 601 AND NOT FASTINSTALL = "1" ) OR ACTION = "ADMIN"</Condition>
Neither of these seem to work. Am I just missing something here, or is there a different, better way to do this?
A feature with Feature/#Level="0" will never be installed in an admin install, per the MSI SDK:
During an administrative installation,
the installer creates a source image
for all features in the product except
those feature with 0 in the Level
column of the Feature table.
So you need to reverse your logic; set the feature level to something greater than zero and use Conditions to set it to zero for non-admin installs.

SSIS - Skip Missing Files

I have a SSIS 2008 package that calls about 25 other SSIS packages.
Each of those child packages loads a specific file into a table. But sometimes one or more of these input files will be missing.
How can I let a child package fail (because a file is missing) but let the rest of the parent package keep on running?
I've tried increasing the maximum error count on the parent package, the tasks in the parent package that call each child, and in the child package itself. None of that seemed to make any difference. I still get this error when I run it with a file missing:
SSIS Warning Code DTS_W_MAXIMUMERRORCOUNTREACHED. The
Execution method succeeded, but the
number of errors raised (2) reached
the maximum allowed (1); resulting in
failure. This occurs when the number
of errors reaches the number specified
in MaximumErrorCount. Change the
MaximumErrorCount or fix the errors.
Edit:
failpackageonfailure and faulparentonfailure are already all set to false everywhere.
I haven't tried this, but this is how I would approach it.
Create a variable for the file name and the child package name.
Use a For Each Loop container. Have it go through the location of the files and pull the file names one at a time. Use the file name to change the child package name variable. In the container have the task to run the child package and have the name dynamically set based on the values of the child package name variable.
Then it should only try to run the child packages which have appropriate files.
in the properties of the execute package task, you can set the failpackageonfailure and faulparentonfailure. i haven't worked with these, but you can probably play with them to get your desired results.
Side note: for simplicity, I'd set these settings on the parent SSIS package.
There is a MaximumErrorCount values at the Sequence Containers & package level. If you're using this be sure your values are in-sync because the package level settings take precedence.
Another option is the ForcedExecutionValue.
To set this up, load the properties tab for each of container and:
1) ForceExecutionValue to TRUE
This will cause the container to return whatever value you put in the variable (see step #2), despite the outcome of the task(s).
2) ForcedExecutionValue to 0
This acts a return value for that task, and sets it to 0 (true, think "return 0" as in C++).
I hope that helps.
This will cause the package to
Load the properties using "ForcedExecutionValue" to 0, then Then set the Force
I have done this kind of scenario development, first plan the package execution method as whenever you will get a file we need to process the package if not either fail or leave the package ultimately our target is to process all the package of files existing. take a variable for all the packages. set the variable to "Y" or "N" on the existing of the file using script component or connection string in the parent package. the existing condition to execute the package on the value of the variable.
This method gave us desired results of process multiple files with different occurences of source files.
thanks
prav