Your assumption is correct, both the registry value and the file must exist, and the File Version must match the specified criteria for the rule to return True; otherwise, if the registry value is missing or the file is missing, the rule will return False.
Incidentally, a PreRequisite Rule for the Registry KEY Exists is a great additional check to put on a package like this. In the case where the RegKey is absent (which typically means the product to be updated is not installed), having that quick check in the PreReq ruleset can significantly speed up the detection effort. (Essentially a failed PreReq check means the Applicability Rules don't have to be evaluated at all; only the Installed Rules.)
... both the registry value and the file must exist, and the File Version must match the specified criteria for the rule to return True; otherwise, if the registry value is missing or the file is missing, the rule will return False....
Don't you mean that the rule will return True if EITHER (1) the registry value exists and the file version matches OR (2) the registry value does not exist? Take the full install and the upgrade packages for Jave Runtime Environment 7u11 (x64), for example. The description for the full install packagesays that it does not require a previous version of Java to be installed. This package has only one applicability rule as follows:
FileVersionPrependRegSz Hive="HKEY_LOCAL_MACHINE"Subkey="SOFTWARE\JavaSoft\Java Runtime Environment\1.7"Value="JavaHome"RegType32="false"Path="bin\java.dll"Comparison="LessThan"Version="188.8.131.52"
A machine with no Java installed would not have the registry key SOFTWARE\JavaSoft\Java Runtime Environment\1.7 or the value JavaHome. If the rule evaluated as you described, wouldn't this cause the rule to return False and prevent the package from being installed? It seems that would have to return True, not False, if the registry value doesn't exist. I assumed that this was why the (upgrade only) package includes a second applicability rule using the "registry key exists" rule that you described. It's interesting that the programmers put this rule in the applicability section, rather than in the prerequisite section as you described, though. It does seem that it could save a bit of time the other way.
It's a Great Question, Andrew, and now I'm somewhat disconcerted at the situation...
FileVersionPrependRegSz Hive="HKEY_LOCAL_MACHINE"Subkey="SOFTWARE\JavaSoft\Java Runtime Environment\1.7"
Value="JavaHome "RegType32="false" Path="bin\java.dll" Comparison="LessThan" Version="184.108.40.206"
If the registry key HKLM\Software\JavaSoft\Java Runtime Environment\1.7 exists
AND the registry value "JavaHome" exists in that registry key
AND the JAVA.DLL file exists in the ~\bin subfolder
AND the version of the JAVA.DLL file is less than "220.127.116.11"
then the rule will return TRUE.
Presumably, otherwise, the rule should return FALSE (that's the way I've always understood the rule behaviors); however, I did some "reading between the lines" in the Rules documentation, and it may be that this rule only returns FALSE when File Version can be validated (i.e. when the file actually does exist and the File Version is NOT less than the specified value).
Ultimately the purpose of this rule is to determine if JRE7 is already installed. It's looking for C:\Program Files\Java\jre7\bin\java.dll.
If that file exists, and its version is less than 18.104.22.168 (which is the actual JRE7u11 update file, the third octet is the update value with a trailing 0), then the rule is TRUE (remember this Full package is not only for FRESH installations, but it also is applicable in UPGRADE scenarios). As a result, the JRE7 Full Install package isInstallable, and the update will be reported as "Not Installed".
If JRE7u11 is installed, the JAVA.DLL exists and will have a File Version = 22.214.171.124, and the rule returns FALSE.
Those two points would seem to be incontrovertible.
The question revolves around what if the rule cannot be fully defined because the registry key or registry value is undefined (i.e. missing), and is that different from the case when the FILE is missing, but the registry key/value is present.
In the rule description for this rule type is this somewhat creative statement:
If the rule does not pass verification, the software update is considered not applicable or not installed on the computer.
The interesting part here is the five boldfaced words... Not Applicable and Not Installed are opposite values of the isInstallable boolean returned by the Applicability Ruleset. What this may mean, then, is that the result of this ruleset is conditional upon the evaluation of the Installed Ruleset. In the Installed Ruleset we make the same test with the same rule, but test for EQUALITY. We know that if the file is present, and the u11 file, it returns TRUE (isInstalled). If the file is present, and not the u11 file, it returns FALSE (NotInstalled). The problem, still, is what happens in the ambigous case where JRE7 has never been installed.
One truth does exist. If the registry key, or registry value, or file is missing, then the rule must return the same state in both the Applicability Rules and the Installed Rules. If JRE7 is not installed, the only way the package could be reported as NotInstalled is if the Applicability Rules = isInstallable (TRUE) and the Installed Rules <> isInstalled (FALSE). But how can both of those conditions exist.
This I do not know the answer to, and will inquire with our packaging team for additional guidance and insight. My inclination, still, is that the failure to absolutely evaluate the rule as TRUE, means that it must evaluate to FALSE. But if that were the case -- Applicability Rules <> isInstallable (FALSE) and Installed Rules <> isInstalled (FALSE), the update would be reported as NotApplicable.
However, it's also possible that given ambiguity in both rulesets (you know, this all implies three-state logic in this process, and nothing ever states such three-state logic exists), that this forces the return of isInstallable (e.g. NotInstalled).
This would actually be easy enough to test.. create a package with a PreReq Ruleset that evaluates to TRUE, and leave both Applicability and Installed rulesets blank. If there is such a thing as ambiguity, then an empty ruleset should also return an ambiguous result, and if both rulesets are ambiguous, and the package evaluates to NotIinstalled (PreReq = TRUE and nothing else contradicts that), then we have demonstrated the answer.
I've always understood that an empty ruleset would return FALSE (in the absence of an authoritative TRUE value), and any such updates would always be reported as NotApplicable.
My apologies for the delay in responding. The packaging team did some testing of this back on the 16th, and I've had it on my to-do list to post back, but got sidetracked by some other activities.
This is what was found:
Using a package that currently evaluates as NotInstalled on a Windows 7 x86 system (the test was done with the JRE7u11 x86 full installation package and no JRE7 installed on the target client)...
1. With no Applicability rules, the package was evaluated as NotInstalled. (isInstallable=TRUE; isInstalled=FALSE)
2. With no Applicability rules and no Installed rules, the package was evaluated as NotInstalled. (isInstallable=TRUE; isInstalled=FALSE)
That would seem to imply that in the absence of an explicit FALSE condition, an ambiguous result in the Applicability ruleset will return a TRUE value (resulting in the package being identified as isInstallable).
We also did a third test, removing the existing File Version with Registry rule, and replacing it with a File Version rule and a hard coded pathname. (The path and file, of course, were not present because JRE7 is not installed at all.) That test also returned a NotInstalled state, indicating that in any case .. the absence of the registry key, the registry value, the path or the file being tested by those rules causes a return value of TRUE. So only if the File Version can be absolutely validated and determined would the rule return a FALSE value (i.e. the package IS installed and the current file version is >= the version in the patch package)..
So, your original assumption was absolutely correct. ... and now we've confirmed it.