通过registry检测Office是32位还是64位

现在Office也进来了一个64位安装,在registry中,你会发现安装的Office版本是32位还是64位?

从Office 2010的64位版本上的TechNet文章:

如果您已经安装了包括Microsoft Outlook 2010的Office 2010,则Outlook会在安装它的计算机上设置一个名为“ Bitness ”types为REG_SZ的registry项。 Bitnessregistry项指示Outlook 2010安装是32位还是64位。 对于有兴趣审计计算机以确定其组织中安装的Office 2010版本的pipe理员而言,这可能很有用。

  • registrypath: HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Office \ 14.0 \ Outlook
  • 如果您已安装Office 2013,请使用以下registrypath: HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Office \ 15.0 \ Outlook
  • registry项: Bitness
  • 值:x86或x64

并在同一篇文章的其他地方:

从Office 2010开始,Outlook可用作32位应用程序和64位应用程序。 您select的Outlook版本(位数)取决于Windows操作系统(32位或64位)的版本和计算机上安装的Office 2010(32位或64位)的版本,如果该计算机上已经安装了Office。

决定安装32位或64位版本的Outlook的可行性的因素包括以下内容:

  • 您可以在受支持的32位或64位版本的Windows操作系统上安装32位Office 2010和32位Microsoft Outlook 2010。 只能在受支持的64位操作系统上安装64位版本的Office 2010和64位版本的Outlook 2010。
  • 在64位版本的Windows操作系统上,Office 2010的默认安装是32位Office 2010。
  • 如果Office安装在同一台计算机上,则安装的Outlook版本的位数总是与Office 2010的位数相同。 也就是说,32位版本的Outlook 2010不能安装在已安装64位版本的其他Office 2010应用程序(如64位Microsoft Word 2010或64位Microsoft Excel 2010)的同一台计算机上。 ,则不能在安装了32位版本的其他Office应用程序的同一台计算机上安装64位版本的Outlook 2010。

我已经testing了Otaku的答案,即使没有安装Outlook,即使引用的文章没有清楚地表明这种情况,Outlook的bitness值也会被设置。

添加到vtrz的答案,这是我为Inno Setup写的一个函数:

 const // Constants for GetBinaryType return values. SCS_32BIT_BINARY = 0; SCS_64BIT_BINARY = 6; // There are other values that GetBinaryType can return, but we're // not interested in them. // Declare Win32 function function GetBinaryType(lpApplicationName: AnsiString; var lpBinaryType: Integer): Boolean; external 'GetBinaryTypeA@kernel32.dll stdcall'; function Is64BitExcelFromRegisteredExe(): Boolean; var excelPath: String; binaryType: Integer; begin Result := False; // Default value - assume 32-bit unless proven otherwise. // RegQueryStringValue second param is '' to get the (default) value for the key // with no sub-key name, as described at // http://stackoverflow.com/questions/913938/ if IsWin64() and RegQueryStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe', '', excelPath) then begin // We've got the path to Excel. try if GetBinaryType(excelPath, binaryType) then begin Result := (binaryType = SCS_64BIT_BINARY); end; except // Ignore - better just to assume it's 32-bit than to let the installation // fail. This could fail because the GetBinaryType function is not // available. I understand it's only available in Windows 2000 // Professional onwards. end; end; end; 

遗憾地说,但是Otacku和@ clatonh的方法都不适用于我 – 在registry中(对于没有安装Outlook的64位Office),既没有Outlook Bitness也没有{90140000-0011-0000- 1000-0000000FF1CE}。

我发现的唯一方法,不是通过registry,而是通过使用Windows API函数GetBinaryType (自Windows 2000 Professional以来)来检查其中一个Office可执行文件的位数 。

例如,您可以检查Winword.exe的位数,存储哪个path
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ App Paths \ Winword.exe。

这里是MFC代码片段:

 CRegKey rk; if (ERROR_SUCCESS == rk.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Winword.exe", KEY_READ)) { CString strWinwordPath; DWORD dwSize = MAX_PATH; if (ERROR_SUCCESS == rk.QueryStringValue(strWinwordPath, strWinwordPath.GetBuffer(MAX_PATH), &dwSize)) { strWinwordPath.ReleaseBuffer(); DWORD dwBinaryType; if (::GetBinaryType(strWinwordPath, &dwBinaryType)) { if (SCS_64BIT_BINARY == dwBinaryType) { // Detected 64-bit Office } else { // Detected 32-bit Office } } else { // Failed } } else { // Failed } } else { // Failed } 

注意:如果在.NET环境中调用,查询Outlook应用程序的位数不可靠

在这里,我们在可以被任何应用程序调用的DLL中使用GetBinaryType():

  • 如果主机应用程序是64位C / C ++,则GetBinaryType()将返回SCS_32BIT_BINARY。
  • 如果主机应用程序是64位.NET(我们在64位系统上testing“AnyCPU”),GetBinaryType()返回SCS_64BIT_BINARY。

使用完全相同的DLL代码和完全相同的Outlook二进制path(“c:/ Program Files(x86)/ …”)在同一台计算机上。

这意味着您可能需要使用“IMAGE_NT_HEADERS.FileHeader.Machine”条目自己testing二进制文件。

上帝,我恨一些Windows API的不正确的返回值(另请参阅GetVersion()lie)。

我发现这种方法:

如果HKLM \ Software \ WOW6432Node存在,那么Windows是64位的。

如果存在HKLM \ Software \ WOW6432Node \ Microsoft \ Office,则Office是32位的。

如果HKLM \ Software \ WOW6432Node \ Microsoft \ Office不存在,但HKLM \ Software \ Microsoft \ Office确实存在,则Office是64位。

如果HKLM \ Software \ WOW6432Node不存在,那么Windows和Office是32位的。

来源: Technet论坛

您可以searchregistry{90140000-0011-0000- 0000 -0000000FF1CE}。 如果粗体数字以0开头,则x86是1,即x64

对我来说是在HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Office \ 14.0 \ Registration {90140000-0057-0000-0000-0000000FF1CE}

资源

这个InnoSetup代码在Win 10×64和Office 2016 x86下使用(使用'HKLM \ SOFTWARE \ Microsoft \ Office \ ClickToRun \ Configuration'和'Platform'键)

 [Code] const RegOffice='SOFTWARE\Microsoft\Office\ClickToRun\Configuration'; RegOfficeKey='Platform'; /// <summary> /// Get current HKLM version /// </summary> function GetHKLM: Integer; begin if IsWin64 then Result := HKLM64 else Result := HKLM32; end; /// <summary> /// Check is Microsoft Office is installed or not /// </summary> function IsOfficeInstalled (): Boolean; var platform: string; begin RegQueryStringValue(GetHKLM(), RegOffice, RegOfficeKey, platform); if platform = 'x86' then begin SuppressibleMsgBox('Microsoft Office found (x86 version)' , mbConfirmation, MB_YESNO or MB_DEFBUTTON1, IDYES); Result := True; end else if platform = 'x64' then begin SuppressibleMsgBox('Microsoft Office found (x64 version)', mbConfirmation, MB_YESNO or MB_DEFBUTTON1, IDYES); Result := True; end else begin SuppressibleMsgBox('Microsoft Office NOT found' + platform + '.', mbConfirmation, MB_YESNO or MB_DEFBUTTON1, IDYES); Result := False; end; end; 

我在这些文件夹中没有一个叫做位的密钥。 我在这两个文件夹中都有一个名为“default”的键,值为“未设置”。我的电脑附带了Office 2010启动器(我假设是64位)。 我删除它,并试图做一个完整的32位的办公室安装。 我不断收到以下消息。 该文件不兼容,请检查您是否需要x86或x64版本的程序。

对我有什么build议?

@clatonh:这是我的电脑上registry的path:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Office \ 14.0 \ Registration {90140000-002A-0000-1000-0000000FF1CE}它绝对是一个64位的32位安装OS。

我以前一直盲目地遵循基于MSDN文档的答案。 今天,这个结果是不够的。 在安装有Office Home和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。 如果您的应用程序不以相同的方式访问registry,则可能会看到不同的结果。

这是我能够用VBscript来检测Office 64位Outlook:

 Dim WshShell, blnOffice64, strOutlookPath Set WshShell = WScript.CreateObject("WScript.Shell") blnOffice64=False strOutlookPath=WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\outlook.exe\Path") If WshShell.ExpandEnvironmentStrings("%PROCESSOR_ARCHITECTURE%") = "AMD64" And _ not instr(strOutlookPath, "x86") > 0 then blnOffice64=True wscript.echo "Office 64" End If 

我赢了7 64位+ Excel 2010 32位。 registry是HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Office \ 14.0 \ Registration {90140000-002A-0000-1000-0000000FF1CE}

所以这可以告诉OS的位,而不是Office的位

我已经在基于InnoSetup的脚本中find了安全可靠的方法,通过使用Win32 API函数来了解特定的应用程序是32位还是64位(在我的情况下,我需要testingExcel)。 这个函数被称为GetBinaryType() ,它来自`kernel32'(尽pipe它的名字是32位和64位的),并且直接看着exe的头文件。

这篇维基百科文章指出:

在64位版本的Windows上,应用程序文件有两个文件夹; "Program Files"文件夹包含64位程序, "Program Files (x86)"文件夹包含32位程序。

所以如果程序安装在C:\Program Files它是一个64位版本。 如果它安装在C:\Program Files (x86) ,则是32位安装。

另一种检测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"; } 

您可以find其他Office组件的typelib id,并replace该函数的第一行。 以下是有趣的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 

以上所有的lib id都是通过Windows SDK工具OLE-COM Object Viewerfind的,通过使用它可以find更多的lib id。

这种方法的好处是,它适用于所有版本的办公室,并为您感兴趣的每个单一组件提供控制。 此外,这些密钥位于HKEY_CLASSES_ROOT中,并深深地集成到系统中,因此即使在沙箱环境中也不可能访问这些密钥。

注意:上面列出的detectVersion函数不起作用 。 我有一个64位版本的Office,和一个单独的32位。这两个版本使用此函数返回“32位”。

手动检查registry导致相同的结论:64位和32位(Office 2010 x64和Office 2013 32位)报告32位。

就我个人而言,我认为Office团队应该简单地编写和维护一个易于获取的registry项。 所有插件都需要引用这个,而目前的“猜测”是开发人员被迫使用的糟糕的方法。

你不需要编写脚本。 看看我偶然发现的这个页面:

https://social.msdn.microsoft.com/Forums/office/en-US/43499ae0-bcb5-4527-8edb-f5a955987b56/how-to-detect-whether-installed-ms-office-2010-is-32-或-64位?论坛= worddev

总结:

产品代码中的第四个字段表示产品的位数。

{BRMMmmmm-PPPP-LLLL- p 000-D000000FF1CE} p000

0代表x86,1代表x64 0-1(这也适用于MSOffice 2013)

在registry中search您感兴趣的办公室组件的安装path,例如Excel 2010查看软件(Wow6432Node)\ Microsoft \ Office \ 14.0 \ Excel \ InstallRoot。 它只会在32位registry或64位registry都不是两个。

Outlook位度registry项在我的机器上不存在。

确定Outlook Bitness的一种方法是检查Outlook.exe,确定它是32位还是64位。

具体来说,您可以检查[IMAGE_FILE_HEADER.Machine] [1]types,这将返回一个指示处理器types的值。

对于这个讨论的一个很好的背景,在阅读一个文件的PE Header时,阅读这个(过时的链接)

IMAGE_NT_HEADERS结构是存储PE文件细节的主要位置。 它的偏移量由文件开始处的IMAGE_DOS_HEADER中的e_lfanew字段给出。 实际上有两个版本的IMAGE_NT_HEADER结构,一个用于32位可执行文件,另一个用于64位版本。 差异是如此微小,以至于我们认为它们与本次讨论的目的相同。 区分这两种格式的唯一正确的,微软认可的方式是通过IMAGE_OPTIONAL_HEADER中的Magic字段的值(稍后描述)。

IMAGE_NT_HEADER由三个字段组成:

typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

你可以在这里获得C#代码。

Magic字段位于IMAGE_OPTIONAL_HEADER结构的开始位置,距_IMAGE_NT_HEADERS开始的偏移量24位置有2个字节。 它的值为32位的0x10B和64位的0x20B。

不是通过registry,而是通过命令行工具:

https://stackoverflow.com/a/6194710/2885897

C:\ Users \ me> assoc .msg

的.msg = Outlook.File.msg.15

C:\ Users \ me> ftype Outlook.File.msg.15

Outlook.File.msg.15 =“C:\ Program Files( x86 )\ Microsoft Office \ Root \ Office16 \ OUTLOOK.EXE”/ f“%1”

最简单的方法:把您的Office 2016应用程序上的关于图标。 示例Excel

1)打开Excel – >文件 – >选项 – >自定义function区

2)你会看到2个窗格。 从&自定义function区select命令

3)从select命令,select所有命令

4)从列表中select关于(Excel)

5)从自定义色带疼痛,突出显示任何项目(如视图),你想要把关于图标

6)点击底部的新build组

7)单击位于两个窗格之间的添加button。 DONE

现在,当你点击Excel中的视图选项卡,然后点击左键,你会看到32位或64位

我find了检查办公室位置的方法。

我们可以使用这个registry项检查office 365和2016 bitness:

 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration 

平台x86为32位。

 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration 

64位平台x64。

请检查…

我发现了一个更简单的方法。 使用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 

当以这种方式请求OperatingSystem时,我们会得到奇怪的结果, 看看这里。 PC3是我的。

我希望这对你们有用。 对不起,没有代码; 我的脚本大多是function性的。

编辑 :不要忘记添加代码来完成检索数据后closuresExcel。
昨天testing了这个代码之后,我突然发现了大量的Excel打开和崩溃。
这将确保您将保持用户和pipe理员的快乐(:

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

如果只想知道已安装的Office 2010版本的位数,则在任何Office 2010应用程序中,只需单击“文件”,然后单击“帮助”即可。 有关版本号的信息将被列出,旁边的括号内将是(32位)或(64位)。

打开Outlook 2013>文件> Office帐户>关于Outlook>点击大“?关于Outlook”button>阅读popup窗口说明