[registry] Detect whether Office is 32bit or 64bit via the registry

Now that Office also comes in a 64bit install, where in the registry do you find out if the version of Office installed is 32bit or 64bit?

This question is related to registry ms-office 32bit-64bit office-2010

The answer is


If one wants to know only what bit number an installed version of Office 2010 is, then in any application of Office 2010, just click on File, then on Help. Information about version number will be listed, and next to that, in parentheses, will be either (32-bit) or (64-bit).


Best easy way: Put the ABOUT Icon on your Office 2016 Application. Example Excel

1) Open Excel -> File -> Options -> Customize Ribbon

2) You 'll see 2 panes. Choose Commands From & Customize The Ribbon

3) From Choose Command, Select All Commands

4) From the resulting List Highlight About (Excel)

5) From the Customize The Ribbon Pain, Highlight Any Item (ex. View) where you want to put the About icon

6) Click New group at the bottom

7) Click the add button located between the two pane. DONE

Now when you click the View Tab in excel and click about you'll see 32 bit or 64 bit


Outlook Bitness registry key does not exist on my machine.

One way to determine Outlook Bitness is by examining Outlook.exe, itself and determine if it is 32bit or 64bit.

Specifically, you can check the [IMAGE_FILE_HEADER.Machine][1] type and this will return a value indicating processor type.

For an excellent background of this discussion, on reading the PE Header of a file read this (outdated link), which states;

The IMAGE_NT_HEADERS structure is the primary location where specifics of the PE file are stored. Its offset is given by the e_lfanew field in the IMAGE_DOS_HEADER at the beginning of the file. There are actually two versions of the IMAGE_NT_HEADER structure, one for 32-bit executables and the other for 64-bit versions. The differences are so minor that I'll consider them to be the same for the purposes of this discussion. The only correct, Microsoft-approved way of differentiating between the two formats is via the value of the Magic field in the IMAGE_OPTIONAL_HEADER (described shortly).

An IMAGE_NT_HEADER is comprised of three fields:

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

and you can get the c# code here.

The Magic field is at the start of the IMAGE_OPTIONAL_HEADER structure, 2 bytes at offset 24 from the start of the _IMAGE_NT_HEADERS. It has values of 0x10B for 32-bit and 0x20B for 64-bit.


You do not need to script it. Look at this page that I stumbled across:

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

To summarize:

The fourth field in the productcode indicates the bitness of the product.

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

0 for x86, 1 for x64 0-1 (This also holds true for MSOffice 2013)


I have win 7 64 bit + Excel 2010 32 bit. The registry is HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Registration{90140000-002A-0000-1000-0000000FF1CE}

So this can tell bitness of OS, not bitness of Office


Attention: querying the bitness of the Outlook Application does NOT reliably work if called in .NET environment.

Here, we use GetBinaryType() in a DLL that can be called by any application:

  • If the host application is 64 bit C/C++, GetBinaryType() returns SCS_32BIT_BINARY.
  • If the host application is 64 bit .NET (we tested "AnyCPU" on a 64 bit system), GetBinaryType() returns SCS_64BIT_BINARY.

With exactly the same DLL code and exactly the same Outlook binary path ("c:/Program Files (x86)/...") on the same computer.

Meaning that you might need to test the binary file yourself using "IMAGE_NT_HEADERS.FileHeader.Machine" entry.

God, I hate the incorrect return values of some Windows APIs (see also GetVersion() lie).


I've found a secure and reliable way in my InnoSetup-based script to understand whether a particular application is 32-bit or 64-bit (in my case I needed to test Excel), by using a Win32 API function. This function is called GetBinaryType(), it comes from `kernel32' (despite the name it comes in 32 and 64 bit flavor) and looks directly at the exe's header.


@clatonh: this is the path of the registry on my PC: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Registration{90140000-002A-0000-1000-0000000FF1CE} and it's definitely a 32-bit-installation on a 64-bit OS.


This Wikipedia article states:

On 64-bit versions of Windows, there are two folders for application files; the "Program Files" folder contains 64-bit programs, and the "Program Files (x86)" folder contains 32-bit programs.

So if the program is installed under C:\Program Files it is a 64-bit version. If it is installed under C:\Program Files (x86) it is a 32-bit installation.


To add to vtrz's answer, here's a function I wrote for 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 '[email protected] 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;

Not via the registry but via commandline tools:

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"


I've found a much easier way. Using Powershell, we can hook Excel as a COM object.

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

When requesting the OperatingSystem this way, we get strange results, have a look here. PC3 is mine.

I hope this works for you guys. Sorry for the lack of code; my scripts are mostly functional.

Edit: Don't forget to add the code to close Excel after you're done retrieving the data.
After testing this code yesterday I had tons of Excel opening and crashing all of a sudden..
This will make sure you'll keep users and admins happy (:

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

EDIT : Solution without touching RegistryKeys - im Sorry Op.

I found out that there is a solution in C# - the original can be found here : https://blogs.msdn.microsoft.com/webdav_101/2016/07/26/sample-detecting-installed-outlook-and-its-bitness/

I modified it a bit for my needs.

just pass the correct outlookPath to 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;



    }

I've previously blindly followed the answer based on the MSDN docs. Today, this turned out to be less than required. On a machine with Office Home and Student installed, which doesn't include Outlook, HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Outlook was present, but HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Outlook was not. I've now changed my code to first look for the "plain" non-Wow6432Node version. If that's present, it'll be used. If not, it will continue by looking at the Wow6432Node version. This is being checked in an Inno Setup-based installer - I don't know which APIs Inno Setup uses. If your app doesn't access the registry in the same way, you might see different results.


I've tested Otaku's answer and it appears that the Outlook bitness value is set even when Outlook is not installed, even though the article referenced does not clearly indicate that this would be the case.


You can search the registry for {90140000-0011-0000-0000-0000000FF1CE}. If the bold numbers start with 0 its x86, 1 is x64

For me it was in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Registration{90140000-0057-0000-0000-0000000FF1CE}

Source


I found the way for checking office bitness .

We can check office 365 and 2016 bitness using this registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration

Platform x86 for 32 bit.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration

Platform x64 for 64 bit.

Please check...


Search the registry for the install path of the office component you are interested in, e.g. for Excel 2010 look in SOFTWARE(Wow6432Node)\Microsoft\Office\14.0\Excel\InstallRoot. It will only be either in the 32-bit registry or the 64-bit registry not both.


Open Outlook 2013 > File > Office account > About Outlook > click large "? About Outlook" button > read popup description


I don't have a key called bitness in either of these folders. I do have a key called "default" in both of these folders and the value is "unset" My computer came with office 2010 starter (I assume 64 bit). I removed it and tried to do a full install of 32 bit office. I keep getting the following message. the file is incompatible, check to see whether you need x86 or x64 version of the program.

any advice for me?


This InnoSetup code is working for me under Win 10x64 and Office 2016 x86 (using 'HKLM\SOFTWARE\Microsoft\Office\ClickToRun\Configuration' and key '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;

I wrote this for Outlook at first. Modified it a little for Word, but it will not work on a standalone install because that key does not show the bitness, only Outlook does.

Also, I wrote it to only support current versions of Office, =>2010

I stripped all the setup and post processing...

: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

In my tests many of the approaches described here fail, I think because they rely on entries in the Windows registry that turn out to be not reliably present, depending on Office version, how it was installed etc. So a different approach is to not use the registry at all (Ok, so strictly that makes it not an answer to the question as posed), but instead write a script that:

  1. Instantiates Excel
  2. Adds a workbook to that Excel instance
  3. Adds a VBA module to that workbook
  4. Injects a small VBA function that returns the bitness of Office
  5. Calls that function
  6. Cleans up

Here's that approach implemented in 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. This approach runs more slowly than others here (about 2 seconds on my PC) but it might turn out to be more reliable across different installations and Office versions.

After some months, I've realised there may be a simpler approach, though still one that instantiates an Excel instance. The VBScript is:

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

This relies on the fact that Application.OperatingSystem, when called from 32-bit Excel on 64-bit Windows returns Windows (32-bit) NT 10.00 or at least it does on my PC. But that's not mentioned in the docs.


Another way to detect the bitness of Office is to find out the typelib.

For example, to detect Outlook's bitness, write a .JS file as following:

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";
}

You could find out other Office component's typelib id, and replace the first line of the function for it. Here is a brief list of interesting IDs:

{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

All above lib id were found through the Windows SDK tool OLE-COM Object Viewer, you could find out more lib id's by using it.

The benefit of this approach is that it works for all versions of office, and provides control on every single component in you interest. Furthermore, those keys are in the HKEY_CLASSES_ROOT and deeply integrated into the system, so it is highly unlikely they were not accessible even in a sandbox environment.


Here's what I was able to use in a VBscript to detect Office 64bit 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

Regret to say, but Both Otacku's and @clatonh's methods aren't working for me - neither have Outlook Bitness nor {90140000-0011-0000-1000-0000000FF1CE} in registry (for 64-bit Office without Outlook installed).

The only way I have found, though, not via the registry, is to check bitness for one of the Office executables with the use of the Windows API function GetBinaryType (since Windows 2000 Professional).

For example, you can check the bitness of Winword.exe, which path is stored under
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Winword.exe.

Here is the MFC code fragment:

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
}

I found this approach:

If HKLM\Software\WOW6432Node exists then Windows is 64-bit.

If HKLM\Software\WOW6432Node\Microsoft\Office exists, then Office is 32-bit.

If HKLM\Software\WOW6432Node\Microsoft\Office does not exist, but HKLM\Software\Microsoft\Office does exist, then Office is 64-bit.

If HKLM\Software\WOW6432Node does not exist, then Windows and Office are 32-bit.

Source: Technet Forums


Examples related to registry

IE Enable/Disable Proxy Settings via Registry How to read value of a registry key c# How to add Python to Windows registry How can I enable Assembly binding logging? Assign command output to variable in batch file Registry key for global proxy settings for Internet Explorer 10 on Windows 8 Run reg command in cmd (bat file)? Command line to remove an environment variable from the OS level configuration How to export/import PuTTy sessions list? Check if registry key exists using VBScript

Examples related to ms-office

How to read data from excel file using c# Excel 2007: How to display mm:ss format not as a DateTime (e.g. 73:07)? What do <o:p> elements do anyway? Access Database opens as read only Microsoft.Office.Core Reference Missing What is a correct MIME type for .docx, .pptx, etc.? VBA: How to display an error message just like the standard error message which has a "Debug" button? How to detect installed version of MS-Office? How can I programmatically freeze the top row of an Excel worksheet in Excel 2007 VBA? Where does VBA Debug.Print log to?

Examples related to 32bit-64bit

MS Access DB Engine (32-bit) with Office 64-bit Running vbscript from batch file Can't start Eclipse - Java was started but returned exit code=13 how much memory can be accessed by a 32 bit machine? CentOS 64 bit bad ELF interpreter Range of values in C Int and Long 32 - 64 bits Is it possible to install both 32bit and 64bit Java on Windows 7? How to find out if an installed Eclipse is 32 or 64 bit version? Missing include "bits/c++config.h" when cross compiling 64 bit program on 32 bit in Ubuntu Should I use Python 32bit or Python 64bit

Examples related to office-2010

Detect whether Office is 32bit or 64bit via the registry