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

前端 未结 28 1042
春和景丽
春和景丽 2020-11-29 21:29

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?

相关标签:
28条回答
  • 2020-11-29 21:59

    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
    
    0 讨论(0)
  • 2020-11-29 22:01

    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.

    0 讨论(0)
  • 2020-11-29 22:01

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

    0 讨论(0)
  • 2020-11-29 22:03

    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).

    0 讨论(0)
  • 2020-11-29 22:06

    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.

    0 讨论(0)
  • 2020-11-29 22:07

    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
    }
    
    0 讨论(0)
提交回复
热议问题