通过注册表检测Office是32位还是64位
-
18-09-2019 - |
题
既然 Office 也提供了 64 位安装,那么您可以在注册表中的哪个位置找到安装的 Office 版本是 32 位还是 64 位?
解决方案
从网上的文章 64位版本的办公室2010年:
如果你已经安装办公室2010年 包括微软展望2010年, Outlook设置一个注册表项名为 位数 的类型 的 在计算机上安装。的 位数 登记册的关键指示是否Outlook2010年安装 是32位或64位。这可能是 有用的管理员 有兴趣审计的计算机 确定安装版本的 办公室2010年在他们的组织。
- 注册的路径: 此\软件\微软\办事处\14.0\Outlook
- 如果你已经安装办公室2013然后用这个 注册的路径: 此\软件\微软\办事处\15.0\Outlook
- 注册处的关键: 位数
- 价值:x86或64
和其他地方在同一篇文章:
开始办公室2010年的前景是 可作为一个32-位应用程序和 64-位应用程序。该版本 (位数)的展望,你的选择 取决于该版本的Windows 操作系统(32位或64位) 和版办公室2010年(32-或 64位)上安装的 计算机,如果办公室已经 安装在计算机。
决定因素的可行性 安装一个32位或64位 版本的Outlook包括 如下:
- 你可以安装32位办公室2010和32位Outlook2010年支持的32位或64位版本的Windows操作系统。你可以安装了64位版本的办公室2010和64位Outlook2010年仅在一个支持64位的操作系统。
- 默认的安装办公室2010年的64位版本的Windows操作系统是32位办公室2010年。
- 中位数的一个安装版本的前景是总是相同位数的办公室2010年,如果办公室安装在同一台计算机。就是说,一个32位的版本展望2010年不可能在同一台计算机上安装在其中的64位版本的其他办公室2010应用程序已经安装,例如64位Microsoft Word2010年或64位Microsoft Excel2010年。同样,64位版本展望2010年不可能在同一台计算机上安装在其中的32位版本的其他办公室应用程序都已经安装。
其他提示
我测试过宅男的回答,看来,在Outlook中位数值设置即使未安装Outlook时,即使引用的文章没有明确指出,这将是这种情况。
要添加到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的方法不是为我工作 - 既不让Outlook位数也不{90140000-0011-0000- 1000 -0000000FF1CE}在注册表(对于64-没有Outlook位Office安装)。
我发现的唯一方法,但是,无法通过注册表,是检查位数与使用Windows API函数的 GetBinaryType 。
例如,可以检查的Winword.exe的位数,其路径被下,点击保存 HKEY_LOCAL_MACHINE \ SOFTWARE \微软\的Windows \ CurrentVersion \ App路径\的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
}
注意:查询位的前景的应用 不可靠的工作 如果调。净的环境。
在这里,我们使用GetBinaryType()DLL中,可以称通过任何应用程序:
- 如果主机应用程序是64位C/C++、GetBinaryType()返回SCS_32BIT_BINARY.
- 如果主机应用程序是64位。网(我们测试了"AnyCPU"在64位系统),GetBinaryType()返回SCS_64BIT_BINARY.
用完全相同的DLL码和完全相同的Outlook二进制的道路("c:/Program 文件(86)/...")在相同的计算机。
这意味着你可能需要测试的二进制文件,自己采用"IMAGE_NT_HEADERS.FileHeader.机器"条目。
上帝,我恨这个错误的返回值的一些窗户Api(另见GetVersion()lie)。
我发现用于检查办公室位数的方式。
我们可以使用此注册表项检查Office 365和2016位数:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration
平台86用于32位。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration
平台64为64位。
请检查...
我发现这种方法:
如果HKLM \ SOFTWARE \ WOW6432Node存在,则视窗是64位的。
如果HKLM \ SOFTWARE \ WOW6432Node \微软\办公室存在,那么办公室是32位。
如果HKLM \ SOFTWARE \ WOW6432Node \微软\ Office不存在,但HKLM \ SOFTWARE \微软\办公室确实存在,则处是64位的。
如果HKLM \ SOFTWARE \ WOW6432Node不存在,然后Windows和Office都是32位。
来源:的Technet论坛
这就是我能够在一个VBScript用来检测办公室64展望:
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
您可以在注册表中搜索{90140000-0011-0000-0000-0000000FF1CE}。如果粗体数字以 0 开头,则为 x86,1 为 x64
对我来说,它是在hkey_local_machine software Microsoft Office 14.0 Ingistration {90140000-0057-0000-0000-0000-0000-0000000FF1}中
这InnoSetup代码是在Win 10x64和Office 2016的x86工作对我来说(使用 'HKLM \ SOFTWARE \微软\办公室\ ClickToRun \配置' 和密钥 '平台')
[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;
我没有叫位数在这些文件夹的关键。我有一个在这两个文件夹名为“默认”键,值为“未设置”我的电脑附带Office 2010入门版(我假设64位)。我删除,并试图做一个完全安装32位Office。我不断收到以下消息。该文件是不兼容的,请检查您是否需要这些程序的x86或x64版本。
对我有什么建议吗?
@clatonh:这是我的电脑上的注册表路径: HKEY_LOCAL_MACHINE \ SOFTWARE \微软\办公室\ 14.0 \ {注册90140000-002A,0000-1000-0000000FF1CE} 而这绝对是一个64位操作系统的32位安装。
我以前盲从根据MSDN文档的答案。如今,这竟然是小于要求。在与Office家庭和学生版安装,一台机器不包括Outlook中,HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Outlook
是存在的,但HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Outlook
没有。现在我已经改变了我的代码先来说一下“普通”非Wow6432Node版本。如果是这样的存在,它会被使用。如果不是,它会通过查看Wow6432Node版本继续。这是正在检查在基于设置的Inno安装程序 - 我不知道哪些API Inno Setup的用途。如果您的应用程序不能访问相同的方式注册表,您可能会看到不同的结果。
我在第一次写此用于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
在我的测试多种方法描述这里失败,我认为,因为它们依赖于条目的窗户注册,是不可靠本,取决于办公室的版本,它是如何被安装等。所以一种不同的做法是不使用的注册在所有(确定,那么严格,使得它不是一个问题的答案为所造成),而是编写脚本是:
- 例化Excel
- 增加了一个工作手册,Excel实例
- 增加了一个VBA模块,工作簿
- 插入一个小VBA功能返回位数的办公室
- 电话功能
- 清理
这里的这种方法实现在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秒钟我的电脑上)但它可能是更可靠的跨越不同的设施和办公室的版本。
几个月之后,我意识到有可能是一个更简单的办法,虽然还是一个实例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
这依赖于这样的事实, Application.OperatingSystem
, ,当时称为32位Excel上的64位Windows返回 Windows (32-bit) NT 10.00
或者至少不会在我的电脑。但是,这是没有提到 文档.
我有赢7 64位+ Excel 2010中的32位。 注册表是HKEY_LOCAL_MACHINE \ SOFTWARE \微软\办公室\ 14.0 \ {登记90140000-002A-0000-1000-0000000FF1CE}
因此,这可以告诉OS的位数,位数不办
我发现我的基于InnoSetup脚本安全和可靠的方式来理解特定的应用是否是32位或64位(在我的情况下,我需要测试Excel)中,通过使用Win32 API函数。该功能被称为GetBinaryType()
,它来自`KERNEL32' (尽管它有32位和64位的风味的名称),并且直接着眼于exe文件的报头中。
这维基百科文章状态:
在Windows的64位版本,存在用于应用程序文件两个文件夹;所述
"Program Files"
文件夹中包含的64位程序,在上述"Program Files (x86)"
文件夹中包含的32位程序。
因此,如果程序被下C:\Program Files
安装它是一个64位版本。如果下C:\Program Files (x86)
安装了它是一个32位的安装。
,以检测办公室的位数的另一种方法是找出类型库。
例如,为了检测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
以上所有的lib ID是通过Windows SDK工具OLE-COM Object Viewer
发现,你可以通过使用它找出更多的lib的ID。
这种方法的好处是,它适用于办公室的所有版本,并在你感兴趣的每一个部件上提供控制。此外,这些密钥是在HKEY_CLASSES_ROOT和深深融入到系统中,所以它是非常不可能,他们无法访问,即使在沙箱环境。
请注意WELL:上面列出的detectVersion功能不起作用。我有办公室的64位版本,以及使用该函数返回的单独一个与32这两个版本“32位”。
检查注册表中手动导致同样的结论:这两种64和32位(Office 2010的x64和办公室2013 32位)报告32位
我个人认为,Office团队应该简单地编写和维护一个容易的地方获得注册表项。所有附加的必要引用此,目前“猜测”是一个贫穷的方法为开发者被强制使用。
您不需要编写脚本。看看我偶然发现的这个页面:
总结一下:
产品代码中的第四个字段指示产品的位数。
{BRMMmmmm-PPPP-LLLL-p000-D000000FF1CE} P000
0 表示 x86,1 表示 x64 0-1(这也适用于 MSOffice 2013)
在注册表中搜索你感兴趣的,例如Office组件的安装路径为Excel 2010的外观软件(Wow6432Node)\微软\办公室\ 14.0 \ EXCEL \ InstallRoot。也只会是无论是在32位的注册表或64位注册表不能同时使用。
我的计算机上不存在 Outlook Bitness 注册表项。
确定 Outlook Bitness 的一种方法是检查 Outlook.exe 本身并确定它是 32 位还是 64 位。
具体来说,您可以检查 [IMAGE_FILE_HEADER.Machine][1] 类型,这将返回一个指示处理器类型的值。
有关本次讨论的优秀背景,请参阅读取文件的 PE 标头 这个(过时的链接), ,其中指出;
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。
不通过注册表而是经由命令行工具:
https://stackoverflow.com/a/6194710/2885897
C:\用户\我> ASSOC的.msg
。味精= Outlook.File.msg.15
C:\用户\我> FTYPE Outlook.File.msg.15
Outlook.File.msg.15 = “C:\ Program Files文件(的 86 强>)\的Microsoft Office \根\ Office16 \ OUTLOOK.EXE”/ F “%1”
最简单的方法:把信息图标您的Office 2016应用程序。例如Excel中
1)打开Excel - >文件 - >选项 - >自定义功能区
2)你会看到2个窗格。选择命令,从与自定义功能区
3)从选择命令,选择所有命令
4)从结果列表突出显示关于(Excel)中
5)从自定义功能区疼痛,突出显示任何项目要放在信息图标(例如查看)
6)点击新组在底部
7)点击位于两个窗格之间添加按钮。 DONE
现在,当您单击Excel中的视图选项卡,然后点击你会看到32位或64位
我已经找到了一种更简单的方法。 使用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是我的。
我希望这对你的作品的家伙。对不起,缺乏代码;我的脚本大多是功能性的。
修改的: 不要忘记添加代码,关闭Excel大功告成检索数据后点击 昨天测试此代码后,我不得不吨的Excel打开和崩溃突然..点击这将确保你让用户和管理员快乐(:
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($msoExcel)
Remove-Variable msoExcel
编辑:解而不触及RegistryKeys - 对不起运算
我发现有在C#中的溶液 - 原可以在这里找到: HTTPS:/ /blogs.msdn.microsoft.com/webdav_101/2016/07/26/sample-detecting-installed-outlook-and-its-bitness/
我修改它有点我的需求。
只是通过正确outlookPath到GetOutlookBitness()
public enum BinaryType : uint
{
SCS_32BIT_BINARY = 0, // A 32-bit Windows-based application
SCS_64BIT_BINARY = 6, // A 64-bit Windows-based application.
SCS_DOS_BINARY = 1, // An MS-DOS – based application
SCS_OS216_BINARY = 5, // A 16-bit OS/2-based application
SCS_PIF_BINARY = 3, // A PIF file that executes an MS-DOS – based application
SCS_POSIX_BINARY = 4, // A POSIX – based application
SCS_WOW_BINARY = 2 // A 16-bit Windows-based application
}
[DllImport("kernel32.dll")]
static extern bool GetBinaryType(string lpApplicationName, out BinaryType lpBinaryType);
public int GetOutlookBitness(string FilePath)
{
int bitness = 0;
if (File.Exists(FilePath))
{
BinaryType type;
GetBinaryType(FilePath, out type);
switch (type)
{
case BinaryType.SCS_32BIT_BINARY:
bitness = 32;
break;
case BinaryType.SCS_64BIT_BINARY:
bitness = 64;
break;
}
}
return bitness;
}
如果一个人想知道什么只有数位的Office 2010的安装的版本,然后在Office 2010中的任何应用程序,只需点击文件,然后帮助。关于版本号的信息将被列出,并且毗邻的是,在括号,将是(32位)或(64位)。
打开Outlook 2013>文件>办公帐号>关于展望>点击大 “?关于展望” 按钮>阅读弹出说明