从注册表读取 Office 路径时,结果不可靠
When reading Office path from registry, result is unreliable
我正在读取从注册表安装的最新版本 Word 的路径,但是即使密钥存在,它也没有 return 路径。
private string GetWordInstallPath()
{
int[] versions = new int[]
{
16, // 2016
15, // 2013
14, // 2010
12, // 2007
11, // 2003
10, // XP
9, // 2000
8, // 98
7 // 97
};
string path = "";
string hklm = @"SOFTWARE\Microsoft\Office\{0}.0\Word\InstallRoot";
foreach (int ver in versions)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(hklm, ver), false);
if (key != null)
{
path = key.GetValue("Path", "").ToString();
key.Close();
break;
}
}
return path;
}
}
在我的例子中,我安装了 Office 2016,我没有安装 Office 2013,但是上面的方法 returns :
C:\Program Files\Microsoft Office 15\root\Office 15\
如您所见,SOFTWARE\Microsoft\Office.0\Word\InstallRoot
没有这样的条目,但是 Office 2016 有一个路径。
为什么在读取 16 的路径时 'key' 为空,但 return 是一个不存在的安装路径,该路径位于我的系统上什至不存在的文件夹中。上述代码的预期结果是遍历 versions
中的值,检查 word 的子项 InstallPath,并在第一个匹配项上 return 该版本的路径,因为它将是最新的安装的 word 版本。
当它为不存在的安装提取值而不是 return 现有安装时,这是不可能做到的。这也需要在不使用 Interop 的情况下完成。
上面的方法是把here, here, here, and to detect that any version is installed I used code from here的点点滴滴拼凑起来的(如下fyi)
private bool IsWordInstalled()
{
Type officeType = Type.GetTypeFromProgID("Word.Application");
return (officeType == null) ? false : true;
}
如果使用默认编译模式或 32 位编译模式,应用程序将自动尝试从 SOFTWARE\WoW6432Node\
* 而不是指定路径 SOFTWARE\
* 获取任何注册表数据。在这种情况下,它的工作方式如下:
32位compile/debug
SOFTWARE\Microsoft\Office.0\Word\InstallRoot
在后台自动翻译成
SOFTWARE\WoW6432Node\Microsoft\Office.0\Word\InstallRoot
由于 WoW6432Node
内的子项中没有 64 位应用程序条目,key
返回 null,因为它不存在。
64 位 compile/debug
SOFTWARE\Microsoft\Office.0\Word\InstallRoot
从指定的确切路径读取正确的密钥。
请务必注意,注册表路径的转换是静默进行的,没有任何错误,并且不会提示用户或在调试日志中提及调整。
此外,任何使用 'preference' 编译为 32 位的应用程序,即使它是混合编译,仍会通过将 WoW6432Node
插入其中来静默翻译密钥。
64 位应用程序将按原样读取注册表项而无需修改,因此可以读取 WoW6432Node 条目以及普通条目。
我正在读取从注册表安装的最新版本 Word 的路径,但是即使密钥存在,它也没有 return 路径。
private string GetWordInstallPath()
{
int[] versions = new int[]
{
16, // 2016
15, // 2013
14, // 2010
12, // 2007
11, // 2003
10, // XP
9, // 2000
8, // 98
7 // 97
};
string path = "";
string hklm = @"SOFTWARE\Microsoft\Office\{0}.0\Word\InstallRoot";
foreach (int ver in versions)
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(hklm, ver), false);
if (key != null)
{
path = key.GetValue("Path", "").ToString();
key.Close();
break;
}
}
return path;
}
}
在我的例子中,我安装了 Office 2016,我没有安装 Office 2013,但是上面的方法 returns :
C:\Program Files\Microsoft Office 15\root\Office 15\
如您所见,SOFTWARE\Microsoft\Office.0\Word\InstallRoot
没有这样的条目,但是 Office 2016 有一个路径。
为什么在读取 16 的路径时 'key' 为空,但 return 是一个不存在的安装路径,该路径位于我的系统上什至不存在的文件夹中。上述代码的预期结果是遍历 versions
中的值,检查 word 的子项 InstallPath,并在第一个匹配项上 return 该版本的路径,因为它将是最新的安装的 word 版本。
当它为不存在的安装提取值而不是 return 现有安装时,这是不可能做到的。这也需要在不使用 Interop 的情况下完成。
上面的方法是把here, here, here, and to detect that any version is installed I used code from here的点点滴滴拼凑起来的(如下fyi)
private bool IsWordInstalled()
{
Type officeType = Type.GetTypeFromProgID("Word.Application");
return (officeType == null) ? false : true;
}
如果使用默认编译模式或 32 位编译模式,应用程序将自动尝试从 SOFTWARE\WoW6432Node\
* 而不是指定路径 SOFTWARE\
* 获取任何注册表数据。在这种情况下,它的工作方式如下:
32位compile/debug
SOFTWARE\Microsoft\Office.0\Word\InstallRoot
在后台自动翻译成
SOFTWARE\WoW6432Node\Microsoft\Office.0\Word\InstallRoot
由于 WoW6432Node
内的子项中没有 64 位应用程序条目,key
返回 null,因为它不存在。
64 位 compile/debug
SOFTWARE\Microsoft\Office.0\Word\InstallRoot
从指定的确切路径读取正确的密钥。
请务必注意,注册表路径的转换是静默进行的,没有任何错误,并且不会提示用户或在调试日志中提及调整。
此外,任何使用 'preference' 编译为 32 位的应用程序,即使它是混合编译,仍会通过将 WoW6432Node
插入其中来静默翻译密钥。
64 位应用程序将按原样读取注册表项而无需修改,因此可以读取 WoW6432Node 条目以及普通条目。