通过注册表检测Office是32位还是64位。

52

现在Office也可以使用64位安装,那么在注册表中,你应该去哪里查找已安装的Office是32位还是64位版本呢?

28个回答

2
你可以搜索注册表中的 {90140000-0011-0000-0000-0000000FF1CE}。如果粗体数字以 0 开头,则为 x86,以 1 开头则为 x64。

对于我来说,它在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Registration{90140000-0057-0000-0000-0000000FF1CE} 中。

来源


以下是用户@Randolf在下面的单独回答中提供的注册表路径:“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Registration{90140000-002A-0000-1000-0000000FF1CE}”,并且这绝对是在64位操作系统上进行的32位安装。 - A N

2
我发现了这个方法:
如果 HKLM\Software\WOW6432Node 存在,则 Windows 是64位操作系统。
如果 HKLM\Software\WOW6432Node\Microsoft\Office 存在,则 Office 是32位版本。
如果 HKLM\Software\WOW6432Node 不存在,但 HKLM\Software\Microsoft\Office 存在,则 Office 是64位版本。
如果 HKLM\Software\WOW6432Node 不存在,则 Windows 和 Office 都是32位版本。
来源:Technet 论坛

2
注意:我在一台32位机器上遇到了wow6432node存在的情况,但是Outlook插件键是唯一的子键。 - JohnZaj
1
我在一台64位机器上使用x64版本的Outlook时遇到了这种情况,但HKLM\Software\Wow6432Node\Microsoft\Office存在。显然,一些添加功能会将它们的键写入两个节点。 - OlivierH
2
我不认为这算是一个普遍规则,因为我没有 HKLM\Software\WOW6432Node\Microsoft\Office,但我的 Outlook 是 32 位的,在 任务管理器 (OUTLOOK.EXE*32) 中可以清楚地看到。 - GreatDane

1

这两个文件夹中都没有名为“bitness”的键。但是我在这两个文件夹中都有一个名为“default”的键,其值为“unset”。我的电脑配备了Office 2010 Starter(我认为是64位)。我已将其卸载并尝试完全安装32位的Office。但我一直收到以下消息:“该文件不兼容,请检查您是否需要程序的x86或x64版本。”

你有什么建议吗?


1

@clatonh:这是我电脑注册表的路径: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Registration{90140000-002A-0000-1000-0000000FF1CE} 而且它肯定是在64位操作系统上进行的32位安装。


你确定吗?我的64位Windows 7上的32位Office 2007,密钥位于HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\12.0\Registration{90120000-0030-0000-0000-0000000FF1CE}。 - Peter Lee
我怀疑您正在使用32位应用程序查看密钥,因为32位应用程序将被放置在file redirectionregistry redirection下。 - phuclv

1

搜索注册表以查找您感兴趣的办公组件的安装路径,例如对于Excel 2010,请查看SOFTWARE(Wow6432Node)\Microsoft\Office\14.0\Excel\InstallRoot。它只会出现在32位注册表或64位注册表中的一个。


1
我最初是为Outlook编写的。稍作修改后适用于Word,但它无法在独立安装中工作,因为该密钥不显示位数,仅Outlook可以。
此外,我编写它仅支持当前版本的Office,=>2010。
我剥离了所有设置和后处理...
:checkarch
    IF NOT "%PROCESSOR_ARCHITECTURE%"=="x86" SET InstallArch=64bit
    IF "%PROCESSOR_ARCHITEW6432%"=="AMD64" SET InstallArch=64bit
    IF "%InstallArch%"=="64bit" SET Wow6432Node=\Wow6432Node
GOTO :beginscript

:beginscript
SET _cmdDetectedOfficeVersion=reg query "HKEY_CLASSES_ROOT\Word.Application\CurVer"
@FOR /F "tokens=* USEBACKQ" %%F IN (`!_cmdDetectedOfficeVersion! 2^>NUL `) DO (
SET _intDetectedOfficeVersion=%%F
)
set _intDetectedOfficeVersion=%_intDetectedOfficeVersion:~-2%


:switchCase
:: Call and mask out invalid call targets
    goto :case!_intDetectedOfficeVersion! 2>nul || (
:: Default case
    ECHO Not installed/Supported
    )
  goto :case-install

:case14
    Set _strOutlookVer= Word 2010 (!_intDetectedOfficeVersion!)
    CALL :GetBitness !_intDetectedOfficeVersion!
    GOTO :case-install  
:case15
    Set _strOutlookVer= Word 2013 (!_intDetectedOfficeVersion!)
    CALL :GetBitness !_intDetectedOfficeVersion!
    GOTO :case-install
:case16
    Set _strOutlookVer= Word 2016 (!_intDetectedOfficeVersion!)
    CALL :GetBitness !_intDetectedOfficeVersion!
    goto :case-install
:case-install
    CALL :output_text !_strOutlookVer! !_strBitness! is installed
GOTO :endscript


:GetBitness
FOR /F "tokens=3*" %%a in ('reg query "HKLM\Software%Wow6432Node%\Microsoft\Office\%1.0\Outlook" /v Bitness 2^>NUL') DO Set _strBitness=%%a
GOTO :EOF

1

我以前盲目地遵循了MSDN文档上的答案。今天,这证明不够用。在安装了Office Home and Student但未包括Outlook的机器上,HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Outlook存在,但HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Outlook不存在。我现在已经更改了我的代码,首先查找“普通”的非Wow6432Node版本。如果存在,将使用它。如果没有,则继续查看Wow6432Node版本。这是在基于Inno Setup的安装程序中进行检查的-我不知道Inno Setup使用哪些API。如果您的应用程序没有以相同的方式访问注册表,则可能会看到不同的结果。


1
在我的测试中,这里描述的许多方法都失败了,我认为这是因为它们依赖于Windows注册表中的条目,这些条目实际上并不可靠地存在,具体取决于Office版本、安装方式等。因此,一个不同的方法是根本不使用注册表(好吧,严格来说,这并不是对所提出问题的答案),而是编写一个脚本,该脚本:
  1. 实例化Excel
  2. 向该Excel实例添加一个工作簿
  3. 向该工作簿添加一个VBA模块
  4. 注入一个返回Office位数的小型VBA函数
  5. 调用该函数
  6. 清理
下面是使用VBScript实现该方法:
Function OfficeBitness()

    Dim VBACode, Excel, Wb, Module, Result

    VBACode = "Function Is64bit() As Boolean" & vbCrLf & _
              "#If Win64 Then" & vbCrLf & _
              "    Is64bit = True" & vbCrLf & _
              "#End If" & vbCrLf & _
              "End Function"

    On Error Resume Next
    Set Excel = CreateObject("Excel.Application")
    Excel.Visible = False
    Set Wb = Excel.Workbooks.Add
    Set Module = Wb.VBProject.VBComponents.Add(1)
    Module.CodeModule.AddFromString VBACode
    Result = Excel.Run("Is64bit")
    Set Module = Nothing
    Wb.Saved = True
    Wb.Close False
    Excel.Quit
    Set Excel = Nothing
    On Error GoTo 0
    If IsEmpty(Result) Then
        OfficeBitness = 0 'Alternatively raise an error here?
    ElseIf Result = True Then
        OfficeBitness = 64
    Else
        OfficeBitness = 32
    End If

End Function

PS. 这种方法比其他方法运行速度更慢(在我的电脑上大约需要2秒),但在不同的安装和 Office 版本中可能会更可靠。

几个月后,我意识到可能有一个更简单的方法,尽管仍然需要实例化 Excel 实例。VBScript 如下:

Function OfficeBitness()
    Dim Excel
    Set Excel = CreateObject("Excel.Application")
    Excel.Visible = False
    If InStr(Excel.OperatingSystem,"64") > 0 Then
        OfficeBitness = 64
    Else
        OfficeBitness = 32
    End if
    Excel.Quit
    Set Excel = Nothing
End Function

这取决于一个事实,即在64位Windows上运行的32位Excel调用Application.OperatingSystem时返回Windows (32-bit) NT 10.00,或者至少在我的PC上是这样。但是文档中没有提到这一点。

0

我找到了一种更简单的方法。 使用PowerShell,我们可以将Excel作为COM对象挂钩。

$user = $env:UserName
$msoExcel = New-Object -ComObject Excel.Application  
$msoExcel | Select-Object -Property OperatingSystem | Out-File "\\SERVER\Path\To\Dump\msoVersion-$user.txt"
exit

以这种方式请求操作系统时,我们会得到奇怪的结果, 看一下这里。PC3是我的。

我希望这对你们有用。抱歉没有代码;我的脚本大多数都是功能性的。

编辑: 不要忘记添加代码以在检索数据完成后关闭Excel。
昨天测试这段代码后,突然间打开了大量的Excel并崩溃了..
这将确保您能让用户和管理员满意(:

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($msoExcel)
Remove-Variable msoExcel

32位或64位是指Office/Excel应用程序,而不是操作系统。在Windows 64位下,默认情况下Office以32位安装,使用WoW技术。 - Pedro Polonia

0

检测 Office 的位数的另一种方法是查找 typelib。

例如,要检测 Outlook 的位数,请编写以下 .JS 文件:

function detectVersion()
    var outlooktlib = "TypeLib\\{00062FFF-0000-0000-C000-000000000046}";
    var HKCR = 0x80000000;

    var loc = new ActiveXObject("WbemScripting.SWbemLocator");
    var svc = loc.ConnectServer(null,"root\\default");
    var reg = svc.Get("StdRegProv");

    var method = reg.Methods_.Item("EnumKey");
    var inparam = method.InParameters.SpawnInstance_();
    inparam.hDefKey = HKCR;
    inparam.sSubKeyName = outlooktlib;
    var outparam = reg.ExecMethod_(method.Name,inparam);
    tlibver = outparam.sNames.toArray()[0];

    method = reg.Methods_.Item("GetStringValue");
    inparam = method.InParameters.SpawnInstance_();
    inparam.hDefKey = HKCR;
    inparam.sSubKeyName = outlooktlib + "\\" + tlibver + "\\0\\win32";
    inparam.sValueName = "";
    outparam = reg.ExecMethod_(method.Name,inparam);
    if(outparam.sValue) return "32 bit";

    method = reg.Methods_.Item("GetStringValue");
    inparam = method.InParameters.SpawnInstance_();
    inparam.hDefKey = HKCR;
    inparam.sSubKeyName = outlooktlib + "\\" + tlibver + "\\0\\win64";
    inparam.sValueName = "";
    outparam = reg.ExecMethod_(method.Name,inparam);
    if(outparam.sValue) return "64 bit";

    return "Not installed or unrecognizable";
}

您可以查找其他Office组件的类型库ID,并将函数的第一行替换为它。以下是一些有趣的ID的简要列表:

{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07} - Access
{00020905-0000-0000-C000-000000000046} - Word
{00020813-0000-0000-C000-000000000046} - Excel
{91493440-5A91-11CF-8700-00AA0060263B} - Powerpoint
{0002123C-0000-0000-C000-000000000046} - Publisher
{0EA692EE-BB50-4E3C-AEF0-356D91732725} - OneNote 2010+
{F2A7EE29-8BF6-4A6D-83F1-098E366C709C} - OneNote 2007

所有上述的库 ID 都是通过 Windows SDK 工具 OLE-COM Object Viewer 找到的,您可以使用它找到更多的库 ID。

这种方法的好处是它适用于所有版本的 Office,并提供了对您感兴趣的每个单独组件的控制。此外,这些键位于 HKEY_CLASSES_ROOT 中,并深度集成到系统中,因此即使在沙箱环境中也很难无法访问。


这对我不起作用。我肯定安装了Office 2010的64位版本,但是您上面提到的所有typelib键中都没有包含“win64”键路径;它们都有win32路径。我是否误解了您的解决方案? - JohnZaj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接