65.9K
CodeProject 正在变化。 阅读更多。
Home

Microsoft Office 版本检测器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2012年10月25日

CPOL

2分钟阅读

viewsIcon

35524

这是 “Microsoft Office 版本检测器” 的一个替代方案。

引言

在时间紧迫的情况下,并且在长时间寻找获取 Microsoft Office 应用程序信息(全部或特定应用程序,例如 Word、Excel、Access 等)的方法后,我在这里 CodeProject 上找到了一些很棒的文章,并将它们从 C# 翻译过来/结合起来,以获取我所需的数据。 虽然我不是代码的作者,但我确实设法让它适用于我的特定情况。 有很多其他方法可以做到这一点,这绝不是最好的或唯一的方法。

此外,你可以从很多方向入手,进行很多修改和补充,例如输出到网格,更快、更高效等等。 希望这能帮助任何迷茫或难以找到类似帮助的人。

背景

这是我在 CodeProject 上的第一篇文章,其基础来自 Warren Stevens 撰写的 Microsoft Office 版本检测器。

全文归功于 Warren Stevens 和 Daneil Leykauf 在 这篇文章和评论中,以及 Niskof 在 他的文章中。

再次声明,这并非我的原创作品,但我发现这些文章在完成我的任务时非常有帮助。

我需要确定 MS Office 应用程序的详细信息,例如以下内容

  1. 完整的应用程序 EXE 名称
  2. 原始文件名
  3. 完整的应用程序 EXE 路径
  4. 文件版本号
  5. 语言

Using the Code

使用方法非常简单。 为了测试目的,我在表单加载事件中添加了一个调用。

Private Sub frmOfficeVersion_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    ListAllOfficeVersions() 'to list all of the apps
    ListSpecificOfficeVersion(MSOfficeApp.Word_Application)
End Sub 

代码如下

Option Strict On    '<--thanks for the reminder kevininstructor

Imports Microsoft.Win32
Imports System.IO

Public Class frmOfficeVersion

    ''' Possible Office apps.
    Enum MSOfficeApp
        Access_Application
        Excel_Application
        Outlook_Application
        PowerPoint_Application
        Word_Application
        FrontPage_Application
    End Enum

    ''' Possible versions
    Enum Version
        Version2007 = 12
        Version2003 = 11
        Version2002 = 10
        Version2000 = 9
        Version97 = 8
        Version95 = 7
    End Enum

    ''' Lists all available MS Office apps and version in console window
    Public Sub ListAllOfficeVersions()
        'created by Daneil Leykauf from codeproject.com
        'under this article https://codeproject.org.cn/Articles/16622/Microsoft-Office-Version-Detector
        'at this profile h ttp://codeproject.org.cn/script/Membership/View.aspx?mid=4804015
        'modified by aalvarez of dane-elec 10/24/12
        Dim strApp As String = Nothing

        For Each s As String In [Enum].GetNames(GetType(MSOfficeApp))
            If Not IsNothing(GetComponentPath(CType([Enum].Parse(GetType(MSOfficeApp), s), _
                 MSOfficeApp), True)) Then
                strApp = GetComponentPath(CType([Enum].Parse(GetType(MSOfficeApp), s), _
                   MSOfficeApp), True).ToString
            Else
                strApp = "Not Found Err."
            End If

            If File.Exists((strApp).ToUpper) Then
                Dim _fileVersion As FileVersionInfo = FileVersionInfo.GetVersionInfo(strApp.ToUpper)
                Debug.Print(s & vbTab & GetVersionsString(CType([Enum].Parse_
                                   (GetType(MSOfficeApp), s), MSOfficeApp)))
                Debug.Print("App Path Full = " & (strApp).ToUpper)
                Debug.Print("App Exists: " & _fileVersion.ToString)
            Else
                Debug.Print(s & vbTab & GetVersionsString(CType([Enum].Parse_
                                         (GetType(MSOfficeApp), s), MSOfficeApp)))
            End If

            Debug.Print(vbCrLf & "=================" & vbCrLf)

        Next
    End Sub

    Public Sub ListSpecificOfficeVersion(ByVal MsApplication As MSOfficeApp)
        Debug.Print(GetComponentPath(MsApplication))
        Dim strApp As String = Nothing
        If Not IsNothing(GetComponentPath(MsApplication, True)) Then
            strApp = GetComponentPath(MsApplication, True).ToString
        Else
            strApp = "Not Found Err."
        End If

        If File.Exists((strApp).ToUpper) Then
            Dim _fileVersion As FileVersionInfo = FileVersionInfo.GetVersionInfo(strApp.ToUpper)
            Debug.Print(vbTab & GetVersionsString(MsApplication))
            Debug.Print("App Path Full = " & (strApp).ToUpper)
            Debug.Print("App Exists: " & _fileVersion.ToString)
        Else
            Debug.Print(vbTab & GetVersionsString(MsApplication))
        End If

        Debug.Print(vbCrLf & "=================" & vbCrLf)

    End Sub

    ''' Returns version number as integer
    ''' Value is 0 if no version could be detected
    Public Shared Function GetVersionsID(ByVal app As MSOfficeApp) As Integer
        Dim strProgID As String = [Enum].GetName(GetType(MSOfficeApp), app)
        strProgID = Replace(strProgID, "_", ".")
        Dim regKey As RegistryKey
        regKey = Registry.LocalMachine.OpenSubKey("Software\Classes\" & strProgID & "\CurVer", False)
        If IsNothing(regKey) Then Return 0
        Dim strV As String = CStr(regKey.GetValue("", Nothing, RegistryValueOptions.None))
        Debug.Print(strV)
        regKey.Close()

        strV = Replace(Replace(strV, strProgID, ""), ".", "")
        Return CInt(strV)
    End Function

    ''' Returns the version string
    Public Shared Function GetVersionsString(ByVal app As MSOfficeApp) As String
        Dim strProgID As String = [Enum].GetName(GetType(MSOfficeApp), app)
        strProgID = Replace(strProgID, "_", ".")
        Dim regKey As RegistryKey
        regKey = Registry.LocalMachine.OpenSubKey("Software\Classes\" & strProgID & "\CurVer", False)
        'Debug.Print(regKey.ToString)
        If IsNothing(regKey) Then Return "No version detected."
        Dim strV As String = CStr(regKey.GetValue("", Nothing, RegistryValueOptions.None))
        'Debug.Print(strV)
        regKey.Close()

        strV = Replace(Replace(strV, strProgID, ""), ".", "")
        Return [Enum].GetName(GetType(Version), CInt(strV))
    End Function

    Private Function GetComponentPath(ByVal _component As MSOfficeApp, _
                    Optional ByVal blnFullPath As Boolean = False) As String
        'code in c# by Niskov from codeproject.com
        'https://codeproject.org.cn/script/Membership/View.aspx?mid=4840737
        '
        'translated and modified to vb.net by aalvarez of Dane-Elec
        '=======================================================

        Const RegKey As String = "Software\Microsoft\Windows\CurrentVersion\App Paths"
        Dim toReturn As String = Nothing
        Dim _key As String = Nothing

        Select Case _component
            Case MSOfficeApp.Word_Application
                _key = "winword.exe"

            Case MSOfficeApp.Excel_Application
                _key = "excel.exe"

            Case MSOfficeApp.PowerPoint_Application
                _key = "powerpnt.exe"

            Case MSOfficeApp.Outlook_Application
                _key = "outlook.exe"

            Case MSOfficeApp.Access_Application
                _key = "MSACCESS.exe"

            Case MSOfficeApp.FrontPage_Application
                _key = "FrontPg.exe"

        End Select

        _key = _key.ToUpper

        'looks inside CURRENT_USER:
        Dim _mainKey As RegistryKey = Registry.CurrentUser

        Try
            _mainKey = _mainKey.OpenSubKey(RegKey & "\" & _key, False)
            If _mainKey IsNot Nothing Then
                toReturn = _mainKey.GetValue(String.Empty).ToString()
                If blnFullPath Then toReturn = toReturn & _key
            End If
        Catch
        End Try

        'if not found, looks inside LOCAL_MACHINE:
        _mainKey = Registry.LocalMachine
        If String.IsNullOrEmpty(toReturn) Then
            Try
                _mainKey = _mainKey.OpenSubKey(RegKey & "\" & _key, False)
                If _mainKey IsNot Nothing Then
                    toReturn = _mainKey.GetValue("Path").ToString()
                    If blnFullPath Then toReturn = toReturn & _key
                End If
            Catch
            End Try
        End If

        'closing the handle:
        If _mainKey IsNot Nothing Then
            _mainKey.Close()
        End If

        Return toReturn

    End Function

    Private Sub frmOfficeVersion_Load(sender As System.Object, _
                           e As System.EventArgs) Handles MyBase.Load
        'ListAllOfficeVersions()
        ListSpecificOfficeVersion(MSOfficeApp.Word_Application)
    End Sub

End Class

然后返回类似于以下内容的输出

=================
Word_Application Version2003
App Path Full = C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE11\WINWORD.EXE
App Exists: File:             C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE11\WINWORD.EXE
InternalName:     WinWord
OriginalFilename: WinWord.exe
FileVersion:      11.0.8345
FileDescription:  Microsoft Office Word
Product:          Microsoft Office 2003
ProductVersion:   11.0.8345
Debug:            False
Patched:          False
PreRelease:       False
PrivateBuild:     False
SpecialBuild:     False
Language:         Language Neutral

=================
FrontPage_Application No version detected.
=================
C:\Program Files\Microsoft Office\OFFICE11\
C:\Program Files\Microsoft Office\OFFICE11\Version2003
App Path Full = C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE11\WINWORD.EXE
App Exists: File:             C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE11\WINWORD.EXE
InternalName:     WinWord
OriginalFilename: WinWord.exe
FileVersion:      11.0.8345
FileDescription:  Microsoft Office Word
Product:          Microsoft Office 2003
ProductVersion:   11.0.8345
Debug:            False
Patched:          False
PreRelease:       False
PrivateBuild:     False
SpecialBuild:     False
Language:         Language Neutral

关注点

再次声明,全文归功于 Warren Stevens、Daneil Leykauf 和 Niskof 在 codeproject.com。

感谢阅读!

在某个时候,我可能需要将此重构为一个 C# 类,届时我会在这里发布更新。

历史

再次声明,这是我的第一篇文章。 感谢 CodeProject.com 上所有乐于助人的朋友们。

C# 更新

感谢大家的建议。 这是快速转换为 C# 的版本。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using System.Collections;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;

namespace csOfficeVersion
{
    public partial class frmOfficeVersion : Form
    {
        public frmOfficeVersion()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            //Console.WriteLine ("This is a test");
            ListAllOfficeVersions();
        }

        //BEGIN===========================>
        /// Possible Office apps.
        public enum MSOfficeApp
        {
            Access_Application,
            Excel_Application,
            Outlook_Application,
            PowerPoint_Application,
            Word_Application,
            FrontPage_Application
        }
        /// Possible versions
        public enum Version
        {
            Version2007 = 12,
            Version2003 = 11,
            Version2002 = 10,
            Version2000 = 9,
            Version97 = 8,
            Version95 = 7
        }

        /// Lists all available MS Office apps and version in console window
        public void ListAllOfficeVersions()
        {
            string strApp = null;
            foreach (string s in Enum.GetNames(typeof(MSOfficeApp)))
            {
                if ((GetComponentPath((MSOfficeApp)Enum.Parse_
                              (typeof(MSOfficeApp), s), true) != null))
                {
                    strApp = GetComponentPath((MSOfficeApp)Enum.Parse_
                              (typeof(MSOfficeApp), s), true).ToString();
                }
                else
                {
                    strApp = "Not Found Err.";
                }
                if (File.Exists((strApp).ToUpper()))
                {
                    FileVersionInfo _fileVersion = _
                            FileVersionInfo.GetVersionInfo(strApp.ToUpper());
                    Debug.Print(s + "\t" + _
                            GetVersionsString((MSOfficeApp)Enum.Parse(typeof(MSOfficeApp), s)));
                    Debug.Print("App Path Full = " + (strApp).ToUpper());
                    Debug.Print("App Exists: " + _fileVersion.ToString());
                }
                else
                {
                    Debug.Print(s + "\t" + _
                      GetVersionsString((MSOfficeApp)Enum.Parse(typeof(MSOfficeApp), s)));
                }
                Debug.Print("\n" + "=================" + "\n");
            }
        }
        public void ListSpecificOfficeVersion(MSOfficeApp MsApplication)
        {
            Debug.Print(GetComponentPath(MsApplication));
            string strApp = null;
            if ((GetComponentPath(MsApplication, true) != null))
            {
                strApp = GetComponentPath(MsApplication, true).ToString();
            }
            else
            {
                strApp = "Not Found Err.";
            }

            if (File.Exists((strApp).ToUpper()))
            {
                FileVersionInfo _fileVersion = FileVersionInfo.GetVersionInfo(strApp.ToUpper());
                Debug.Print("\t" + GetVersionsString(MsApplication));
                Debug.Print("App Path Full = " + (strApp).ToUpper());
                Debug.Print("App Exists: " + _fileVersion.ToString());
            }
            else
            {
                Debug.Print("\t" + GetVersionsString(MsApplication));
            }
            Debug.Print("\n" + "=================" + "\n");
        }

        /// Returns version number as integer
        /// Value is 0 if no version could be detected
        public static int GetVersionsID(MSOfficeApp app)
        {
            string strProgID = Enum.GetName(typeof(MSOfficeApp), app);
            strProgID = strProgID.Replace("_", ".");
            RegistryKey regKey = null;
            regKey = Registry.LocalMachine.OpenSubKey_
                     ("Software\\Classes\\" + strProgID + "\\CurVer", false);
            if ((regKey == null))
                return 0;
            string strV = Convert.ToString(regKey.GetValue("", null, RegistryValueOptions.None));
            Debug.Print(strV);
            regKey.Close();
            strV = strV.Replace(strProgID, "");
            strV = strV.Replace(".", "");

            return Convert.ToInt32(strV);
        }

        /// Returns the version string
        public static string GetVersionsString(MSOfficeApp app)
        {
            string strProgID = Enum.GetName(typeof(MSOfficeApp), app);
            strProgID = strProgID.Replace("_", ".");
            RegistryKey regKey = null;
            regKey = Registry.LocalMachine.OpenSubKey_
                    ("Software\\Classes\\" + strProgID + "\\CurVer", false);
            //Debug.Print(regKey.ToString)
            if ((regKey == null))
                return "No version detected.";
            string strV = Convert.ToString(regKey.GetValue("", null, RegistryValueOptions.None));
            //Debug.Print(strV)
            regKey.Close();
            strV = strV.Replace(strProgID, "");
            strV = strV.Replace(".", "");
            return Enum.GetName(typeof(Version), Convert.ToInt32(strV));
        }

        private string GetComponentPath(MSOfficeApp _component, bool blnFullPath = false)
        {
            //code in c# by Niskov from codeproject.com
            //https://codeproject.org.cn/script/Membership/View.aspx?mid=4840737
            //
            //translated and modified to vb.net by aalvarez of Dane-Elec
            //=======================================================
            const string RegKey = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths";
            string toReturn = null;
            string _key = null;
            switch (_component)
            {
                case MSOfficeApp.Word_Application:
                    _key = "winword.exe";
                    break;
                case MSOfficeApp.Excel_Application:
                    _key = "excel.exe";
                    break;
                case MSOfficeApp.PowerPoint_Application:
                    _key = "powerpnt.exe";
                    break;
                case MSOfficeApp.Outlook_Application:
                    _key = "outlook.exe";
                    break;
                case MSOfficeApp.Access_Application:
                    _key = "MSACCESS.exe";
                    break;
                case MSOfficeApp.FrontPage_Application:
                    _key = "FrontPg.exe";
                    break;
            }
            _key = _key.ToUpper();
            //looks inside CURRENT_USER:
            RegistryKey _mainKey = Registry.CurrentUser;
            try
            {
                _mainKey = _mainKey.OpenSubKey(RegKey + "\\" + _key, false);
                if (_mainKey != null)
                {
                    toReturn = _mainKey.GetValue(string.Empty).ToString();
                    if (blnFullPath)
                        toReturn = toReturn + _key;
                }
            }
            catch
            {
            }
            //if not found, looks inside LOCAL_MACHINE:
            _mainKey = Registry.LocalMachine;
            if (string.IsNullOrEmpty(toReturn))
            {
                try
                {
                    _mainKey = _mainKey.OpenSubKey(RegKey + "\\" + _key, false);
                    if (_mainKey != null)
                    {
                        toReturn = _mainKey.GetValue("Path").ToString();
                        if (blnFullPath)
                            toReturn = toReturn + _key;
                    }
                }
                catch
                {
                }
            }
            //closing the handle:
            if (_mainKey != null)
            {
                _mainKey.Close();
            }
            return toReturn;
        }
        //END=============================>
    }}
© . All rights reserved.