在开发EasyShu的过程中,因为用户体验的倒逼,不得不认真再去学习下如何更好地解决Excel位数的问题。
以下说一下使用代码去获取当前电脑上Excel的位数。
这个方法弊端是需要拿到Excel的Application对象,安装过wps的电脑,可能会破坏正常调用Excel的能力。
如果有办法在VBA环境下使用,那就好简单,上面的方法也行,下面的Win64方法也行。
Public Function IsOffice64() As Boolean
#If Win64 Then
IsOffice64 = True
#Else
IsOffice64 = False
#End If
End Function
这个方法,笔者在EasyShu里短暂用过一段时间,但弊端也是要拿到Excel的Application对象。如果加载对应位数的xll文件后返回结果为true,就证明是这个位数的版本。当然比方法一要折腾了,方法一今天才发现,没用得上,就被方法四给替换了。
这个也是今天的主角,这个方法好处是快速,不用调用Excel程序,读写注册表非常快。准确性还有待EasyShu的用户反馈检验。特别是对一些非默认安装OFFICE路径的,有可能识别不到。
详细核心代码如下:原理为通过注册表位置找到Excel程序的路径,再通过注册表卸载信息里找到OFFICE的GUIDS信息。
最后,正如微软官方定义的GUIDS规则,第四段是存放位数信息。
https://docs.microsoft.com/en-us/office/troubleshoot/office-suite-issues/numbering-scheme-product-code-guids
internal static bool IsExcel64Bit()
{
var uninstallNode = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.ReadKey);
var excelAppNode = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.ReadKey);
var uninstallNode32 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.ReadKey);
var excelAppNode32 = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\App Paths\excel.exe", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.ReadKey);
string excelAppPath;
if (!Environment.Is64BitProcess && excelAppNode32 != null)
{
excelAppPath = excelAppNode32.GetValue("Path").ToString();
}
else
{
excelAppPath = excelAppNode.GetValue("Path").ToString();
}
if (uninstallNode32 != null)
{
var guids = GetGuidsOfOffice(uninstallNode32, excelAppPath);
if (string.IsNullOrEmpty(guids))
{
guids = GetGuidsOfOffice(uninstallNode, excelAppPath);
}
return guids.Split('-')[3].Substring(0, 1) == "1" ? true : false;
}
else
{
var guids = GetGuidsOfOffice(uninstallNode, excelAppPath);
return guids.Split('-')[3].Substring(0, 1) == "1" ? true : false;
}
}
private static string GetGuidsOfOffice(RegistryKey registryKey, string excelAppPath)
{
foreach (string subKeyName in registryKey.GetSubKeyNames())
{
RegistryKey subKey = registryKey.OpenSubKey(subKeyName);
//Console.WriteLine(subKey.GetValue("DisplayName") +"|"+ subKey.GetValue("Publisher") +"|"+ subKey.GetValue("InstallSource"));
if (
subKey.GetValue("DisplayName") != null &&
subKey.GetValue("DisplayName").ToString().ToLower().Contains("office") &&
subKey.GetValue("Publisher") != null &&
subKey.GetValue("Publisher").ToString() == "Microsoft Corporation" &&
subKey.GetValue("InstallSource") != null &&
Path.GetDirectoryName(subKey.GetValue("InstallSource").ToString().TrimEnd('\\')).ToLower() == Path.GetDirectoryName(excelAppPath.TrimEnd('\\')).ToLower()
)
{
return Path.GetFileName(subKey.Name);
}
}
return string.Empty;
}
Excel催化剂开发运营至今3年多,说实话,对用户体验的改善度没有太强烈,相反EasyShu因其定位为付费产品,用户体验倒逼不断地找寻更优解决方案。