如何使用 C# 代码检测系统上是否安装了“.Net Framework 4.6.1 Hotfix”?
How to detect whether “.Net Framework 4.6.1 Hotfix” is installed on System or not using C# Code?
有时人们安装了 .net Framework 4.6.1 而我的应用程序无法在他们的环境中正常工作,除非他们还安装了 .Net Framework 4.6.1 修补程序。所以我必须在每个客户端的机器上明确地解决这个问题。并编写一个程序来执行此检查以帮助支持人员。
这里是检测客户端机器上是否安装了 4.6.1 或更高版本但没有检查 4.6.1 修补程序的示例代码。
注意:64 位操作系统是先决条件。
private static bool CheckIfVCInstalledOrNot()
{
bool vcInstalled = true;
try
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2015to2019x64))
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2017x64))
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2015x64))
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2013x64))
{
vcInstalled = false;
}
}
}
}
}
catch (Exception ex)
{
Utilities.Logging.ErrorLog(ex);
}
return vcInstalled;
}
public enum RedistributablePackageVersion
{
VC2013x64,
VC2015x64,
VC2017x64,
VC2015to2019x64
};
public static class RedistributablePackage
{
/// <summary>
/// Check if a Microsoft Redistributable Package is installed.
/// </summary>
/// <param name="redistributableVersion">The package version to detect.</param>
/// <returns><c>true</c> if the package is installed, otherwise <c>false</c></returns>
public static bool IsInstalled(RedistributablePackageVersion redistributableVersion)
{
try
{
switch (redistributableVersion)
{
case RedistributablePackageVersion.VC2015to2019x64:
var parametersVc2015to2019x64 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\DevDiv\VC\Servicing.0\RuntimeMinimum", false);
if (parametersVc2015to2019x64 == null) return false;
var vc2015to2019x64Version = parametersVc2015to2019x64.GetValue("Version");
if (((string)vc2015to2019x64Version).StartsWith("14"))
{
return true;
}
break;
case RedistributablePackageVersion.VC2017x64:
var paths2017x64 = new List<string>
{
@"Installer\Dependencies\,,amd64,14.0,bundle",
@"Installer\Dependencies\VC,redist.x64,amd64,14.16,bundle" //changed in 14.16.x
};
foreach (var path in paths2017x64)
{
var parametersVc2017x64 = Registry.ClassesRoot.OpenSubKey(path, false);
if (parametersVc2017x64 == null) continue;
var vc2017x64Version = parametersVc2017x64.GetValue("Version");
if (vc2017x64Version == null) return false;
if (((string)vc2017x64Version).StartsWith("14"))
{
return true;
}
}
break;
case RedistributablePackageVersion.VC2015x64:
var parametersVc2015x64 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Installer\Dependencies\{d992c12e-cab2-426f-bde3-fb8c53950b0d}", false);
if (parametersVc2015x64 == null) return false;
var vc2015x64Version = parametersVc2015x64.GetValue("Version");
if (((string)vc2015x64Version).StartsWith("14"))
{
return true;
}
break;
case RedistributablePackageVersion.VC2013x64:
var parametersVc2013x64 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f}", false);
if (parametersVc2013x64 == null) return false;
var vc2013x64Version = parametersVc2013x64.GetValue("Version");
if (((string)vc2013x64Version).StartsWith("12"))
{
return true;
}
break;
}
return false;
}
catch (Exception)
{
return false;
}
}
}
您需要找到修补程序的注册表 DWORD 值并查询该值的注册表。
现在,如果您需要 hotfix 3154529,您可以看到注册表值为“394297”。
因此,您可以从这个 Table 中看出 .net framework 4.6.1 的值大于或等于 393295,带有修补程序的 4.6.1 应为 394297 或更大(较新的修补程序或已应用服务包)。
有时人们安装了 .net Framework 4.6.1 而我的应用程序无法在他们的环境中正常工作,除非他们还安装了 .Net Framework 4.6.1 修补程序。所以我必须在每个客户端的机器上明确地解决这个问题。并编写一个程序来执行此检查以帮助支持人员。
这里是检测客户端机器上是否安装了 4.6.1 或更高版本但没有检查 4.6.1 修补程序的示例代码。 注意:64 位操作系统是先决条件。
private static bool CheckIfVCInstalledOrNot()
{
bool vcInstalled = true;
try
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2015to2019x64))
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2017x64))
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2015x64))
{
if (!Utilities.RedistributablePackage.IsInstalled(Utilities.RedistributablePackageVersion.VC2013x64))
{
vcInstalled = false;
}
}
}
}
}
catch (Exception ex)
{
Utilities.Logging.ErrorLog(ex);
}
return vcInstalled;
}
public enum RedistributablePackageVersion
{
VC2013x64,
VC2015x64,
VC2017x64,
VC2015to2019x64
};
public static class RedistributablePackage
{
/// <summary>
/// Check if a Microsoft Redistributable Package is installed.
/// </summary>
/// <param name="redistributableVersion">The package version to detect.</param>
/// <returns><c>true</c> if the package is installed, otherwise <c>false</c></returns>
public static bool IsInstalled(RedistributablePackageVersion redistributableVersion)
{
try
{
switch (redistributableVersion)
{
case RedistributablePackageVersion.VC2015to2019x64:
var parametersVc2015to2019x64 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\DevDiv\VC\Servicing.0\RuntimeMinimum", false);
if (parametersVc2015to2019x64 == null) return false;
var vc2015to2019x64Version = parametersVc2015to2019x64.GetValue("Version");
if (((string)vc2015to2019x64Version).StartsWith("14"))
{
return true;
}
break;
case RedistributablePackageVersion.VC2017x64:
var paths2017x64 = new List<string>
{
@"Installer\Dependencies\,,amd64,14.0,bundle",
@"Installer\Dependencies\VC,redist.x64,amd64,14.16,bundle" //changed in 14.16.x
};
foreach (var path in paths2017x64)
{
var parametersVc2017x64 = Registry.ClassesRoot.OpenSubKey(path, false);
if (parametersVc2017x64 == null) continue;
var vc2017x64Version = parametersVc2017x64.GetValue("Version");
if (vc2017x64Version == null) return false;
if (((string)vc2017x64Version).StartsWith("14"))
{
return true;
}
}
break;
case RedistributablePackageVersion.VC2015x64:
var parametersVc2015x64 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Installer\Dependencies\{d992c12e-cab2-426f-bde3-fb8c53950b0d}", false);
if (parametersVc2015x64 == null) return false;
var vc2015x64Version = parametersVc2015x64.GetValue("Version");
if (((string)vc2015x64Version).StartsWith("14"))
{
return true;
}
break;
case RedistributablePackageVersion.VC2013x64:
var parametersVc2013x64 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f}", false);
if (parametersVc2013x64 == null) return false;
var vc2013x64Version = parametersVc2013x64.GetValue("Version");
if (((string)vc2013x64Version).StartsWith("12"))
{
return true;
}
break;
}
return false;
}
catch (Exception)
{
return false;
}
}
}
您需要找到修补程序的注册表 DWORD 值并查询该值的注册表。
现在,如果您需要 hotfix 3154529,您可以看到注册表值为“394297”。
因此,您可以从这个 Table 中看出 .net framework 4.6.1 的值大于或等于 393295,带有修补程序的 4.6.1 应为 394297 或更大(较新的修补程序或已应用服务包)。