从注册表中读取Office路径时,结果不可靠

时间:2016-05-05 07:37:01

标签: c# registry ms-office

我正在阅读从注册表安装的最新版Word的路径,但即使密钥存在,它也不会返回路径。

    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,但是上面的方法返回:

  

C:\ Program Files \ Microsoft Office 15 \ root \ Office 15 \

正如您在此处所见,SOFTWARE\Microsoft\Office\15.0\Word\InstallRoot没有此类条目,但Office 2016有一条路径。

Office 2016 path

为什么'关键'读取16的路径时为null,但在我的系统上甚至不存在的文件夹中返回不存在的安装路径。上面代码的预期结果是循环遍历versions中的值,检查子键InstallPath for word,并在第一个匹配时返回该版本的路径,因为它将是最新版本的word安装

当它为不存在的安装提取值而不返回现有安装时,这是不可能的。这也需要在不使用Interop的情况下完成。

上面的方法是将hereherehere中的碎片拼凑起来,并检测是否安装了任何版本我使用了here中的代码(如下fyi)

    private bool IsWordInstalled()
    {
        Type officeType = Type.GetTypeFromProgID("Word.Application");
        return (officeType == null) ? false : true;
    }

1 个答案:

答案 0 :(得分:0)

如果使用默认编译模式或32位编译模式,应用程序将自动尝试从SOFTWARE\WoW6432Node\ *而不是指定的路径SOFTWARE\ *获取任何注册表数据。在这种情况下,它的工作原理如下:

32位编译/调试

  

SOFTWARE \微软\办公室\ 16.0 \字\ InstallRoot

在后台自动翻译为

  

SOFTWARE \ WoW6432Node \微软\办公室\ 16.0 \字\ InstallRoot

由于WoW6432Node内的子项中没有64位应用程序条目,key返回null,因为它不存在。

64位编译/调试

  

SOFTWARE \微软\办公室\ 16.0 \字\ InstallRoot

从指定的确切路径读取正确的密钥。

重要的是要注意,注册表路径的转换是静默发生的,没有任何错误,并且不会提示用户或在调试日志中提及调整。

此外,任何使用'偏好'编译的应用程序到32位,即使它是混合编译,仍会通过插入WoW6432Node来静默转换密钥。

64位应用程序将按原样读取注册表项,无需修改,因此可以读取WoW6432Node条目以及正常条目。