in src/vswhere.lib/InstanceSelector.cpp [34:96]
bool InstanceSelector::Less(const ISetupInstancePtr& a, const ISetupInstancePtr& b) const
{
static ci_less less;
bstr_t bstrVersionA, bstrVersionB;
ULONGLONG ullVersionA, ullVersionB;
FILETIME ftDateA, ftDateB;
// Compare versions.
auto hrA = a->GetInstallationVersion(bstrVersionA.GetAddress());
auto hrB = b->GetInstallationVersion(bstrVersionB.GetAddress());
if (SUCCEEDED(hrA) && SUCCEEDED(hrB))
{
if (m_helper)
{
hrA = m_helper->ParseVersion(bstrVersionA, &ullVersionA);
hrB = m_helper->ParseVersion(bstrVersionB, &ullVersionB);
if (SUCCEEDED(hrA) && SUCCEEDED(hrB))
{
if (ullVersionA != ullVersionB)
{
return ullVersionA < ullVersionB;
}
}
else
{
// a is less than b if we can't parse version for a but can for b.
return SUCCEEDED(hrB);
}
}
else
{
// If ISetupHelper is not available we have only legacy products, or very early pre-releases of VS2017.
// For version 10.0 and newer either should lexigraphically sort correctly.
return less(wstring(bstrVersionA), wstring(bstrVersionB));
}
}
else
{
// a is less than b if we can't get version for a but can for b.
return SUCCEEDED(hrB);
}
// Compare dates.
hrA = a->GetInstallDate(&ftDateA);
hrB = b->GetInstallDate(&ftDateB);
if (SUCCEEDED(hrA) && SUCCEEDED(hrB))
{
auto result = ::CompareFileTime(&ftDateA, &ftDateB);
if (0 == result)
{
auto message = ResourceManager::GetString(IDS_E_UNEXPECTEDDATE);
throw win32_error(E_UNEXPECTED, message);
}
return 0 > result;
}
else
{
// a is less than b if we can't get date for a but can for b.
return SUCCEEDED(hrB);
}
}