【问题标题】:Find Version of Access查找访问版本
【发布时间】:2010-01-07 12:23:11
【问题描述】:

我有下面的代码来确定 Access 的版本。 它可以在大多数 PC 上快速运行。我们还有四台终端服务器。在两台终端服务器上,它运行良好。在另外两个上,此代码需要超过 15 秒才能运行。

所有四个终端服务器都有 Access 2003 运行时。我不明白为什么在两台服务器上运行需要更长的时间。会是权限吗?还是 Access 运行时的安装方式有误?

如果有更好、更快的方法来确定版本,我也会对此感兴趣。 谢谢 厉害了

   ' Determine the Access version by creating an
   ' Access.Application object and looking at
   ' its Version property.
   Private Function GetAccessVersionName() As String
      Dim obj As Object = CreateObject("Access.Application")
      Dim result As String = "Access.Application." & _
          obj.Version
      obj.Quit()
      Return result
   End Function

   ' Get the Access version number from the name.
   Private Function GetAccessVersionNumber() As Integer
      Dim txt As String = GetAccessVersionName()
      Dim pos2 As Integer = txt.LastIndexOf(".")
      Dim pos1 As Integer = txt.LastIndexOf(".", pos2 - 1)
      txt = txt.Substring(pos1 + 1, pos2 - pos1 - 1)
      Return CInt(txt)
   End Function

   ' Get the nice style of the Access version name.
   Public Function GetAccessVersionNiceName() As String

      Try
         Select Case GetAccessVersionNumber()
            Case 8
               Return "Access 97"
            Case 9
               Return "Access 2000"
            Case 10
               Return "Access XP" 
            Case 11
               Return "Access 2003"
            Case 12
               Return "Access 2007"
            Case Else
               Return "unknown"
         End Select
      Catch ex As Exception
         Return "unknown"
      End Try

   End Function

【问题讨论】:

  • 什么版本的 Access?安装的版本?注册到MDB文件的当前版本?3 还是特定MDB/ACCDB/ADP文件格式的Access版本?假定您希望将当前版本注册到 MDB 文件中。我肯定会使用注册表项。虽然,作为一个悲观主义者,我真的很想仔细检查 msaccess.exe 是否存在于注册表项指定的位置。

标签: vb.net ms-access


【解决方案1】:

我认为问题在于对 CreateObject() 的调用。这将运行 Access,我猜在某些机器上可能需要 15 秒。这是获取版本号的另一种方法,它应该会更快 - 它使用注册表中的信息。

Imports Microsoft.Win32

Public Class AccessInterop
    Public Shared Function GetAccessVersionNiceName() As String
        Try
            Dim ClassName As String = GetAccessClassName()
            Select Case GetAccessVersionNumber(ClassName)
                Case 8
                    Return "Access 97"
                Case 9
                    Return "Access 2000"
                Case 10
                    Return "Access XP"
                Case 11
                    Return "Access 2003"
                Case 12
                    Return "Access 2007"
                Case 13
                    Return "Access 2010"
                Case Else
                    Return "unknown"
            End Select
        Catch ex As Exception
            Return "unknown"
        End Try
    End Function

    Private Shared Function GetAccessClassName() As String
        Dim RegKey As RegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("Access.Application\CurVer")
        If RegKey Is Nothing Then
            Throw New ApplicationException("Can not find MS Access version number in registry")
        Else
            Return RegKey.GetValue("")
        End If
    End Function

    Public Shared Function GetAccessVersionNumber(ByVal ClassName As String) As Integer
        Dim VersionNumber As String = ClassName
        While VersionNumber.IndexOf(".") > -1
            VersionNumber = VersionNumber.Substring(VersionNumber.IndexOf(".") + 1)
        End While
        Return VersionNumber.Trim
    End Function
End Class

【讨论】:

【解决方案2】:

此示例很快返回已安装的 Access 版本列表。如果只返回一个,则无需进一步检查。

Const HKEY_LOCAL_MACHINE = &H80000002&

Set fs = CreateObject("Scripting.FileSystemObject")

strComputer = "."
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\default:StdRegProv")
strKeyPathOrg = "SOFTWARE\Microsoft\Office"
strKeyPath = strKeyPathOrg
strValueName = "Path"

strKeyPath = strKeyPathOrg
objReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys

For Each subkey In arrSubKeys

    Select Case subkey
      Case "14.0"
      strKeyPath = strKeyPathOrg & "\" & subkey & "\Access\InstallRoot\"
      objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
      If Not IsNull(strValue) Then
            If fs.FileExists(strValue & "msaccess.exe") Then
               r = r & "Has Access 2010" & vbCrLf
            End If
      End If

      Case "12.0"
      strKeyPath = strKeyPathOrg & "\" & subkey & "\Access\InstallRoot\"
      objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
      If Not IsNull(strValue) Then
            If fs.FileExists(strValue & "msaccess.exe") Then
               r = r & "Has Access 2007" & vbCrLf
            End If
      End If

      Case "11.0"
      strKeyPath = strKeyPathOrg & "\" & subkey & "\Access\InstallRoot\"
      objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
      If Not IsNull(strValue) Then
            If fs.FileExists(strValue & "msaccess.exe") Then
               r = r & "Has Access 2003" & vbCrLf
            End If
      End If

      Case "10.0"
      strKeyPath = strKeyPathOrg & "\" & subkey & "\Access\InstallRoot\"
      objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
      If Not IsNull(strValue) Then
            If fs.FileExists(strValue & "msaccess.exe") Then
               r = r & "Has Access XP" & vbCrLf
            End If
      End If

      Case "9.0"
      strKeyPath = strKeyPathOrg & "\" & subkey & "\Access\InstallRoot\"
      objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
      If Not IsNull(strValue) Then
            If fs.FileExists(strValue & "msaccess.exe") Then
               r = r & "Has Access 2000" & vbCrLf
            End If
      End If

      Case "8.0"
      strKeyPath = strKeyPathOrg & "\" & subkey & "\Access\InstallRoot\"
      objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue
      If Not IsNull(strValue) Then
            If fs.FileExists(strValue & "msaccess.exe") Then
               r = r & "Has Access 97" & vbCrLf
            End If
      End If
    End Select

Next

MsgBox r

【讨论】:

  • 谢谢。但事实证明我只是移动了延迟! :) 我将代码更改为您发布的内容。但我仍然有 15 秒的延迟。我已将其范围缩小到 Dim oAccess As Access.Application 这与我必须检查版本的内容相同。我将以特定形式打开 Access。因此,似乎只要我创建了一个 Access 对象——那就是延迟开始的时候。而且只在这两个服务器上!还有其他想法吗?
  • 抱歉,上面的代码在什么时候引用了 Access 应用程序?
  • @Remou:当该代码在像我日常使用的笔记本电脑这样的机器上运行时会发生什么,该机器在 (8, 9, 11, 12) 上有 4 个这样的子键,并且它们不是按版本顺序 (或反向版本顺序——它们的顺序为 12、11、8、9)。原始代码返回当前在注册表中注册为 Access.Application 类型的 Access 版本,并且一次只有一个可以具有该状态。根据需要完成的任务,您的可能会更好(如果您有 v11 数据库,您可能想查看 v11 是否可以打开它,而不是使用已注册的任何内容)。
  • @DW Fenton 从上面的代码中可以看出,它会很快返回已安装的 Access 版本列表。如果只返回一个,则无需进一步检查,通常是这种情况。我有一个类似的子键列表,并用它来检查此代码是否按预期运行。当安装多个版本时,在注册版本上打开 mdb 并不总是明智的。
  • 我同意这不明智,但原始问题中的代码是确定注册版本。谁知道他会用它做什么——他可能根本不打算用它打开一个数据库。我认为您可以通过在其中包含您的评论解释并承认您的解决方案比原始提问者的代码做得更多来改进您的答案。
【解决方案3】:

这是一个非常漫长的过程,但如果您正在运行已编译的 .NET 应用程序,请确保您运行该应用程序的机器可以访问 Internet,因为 .NET 应用程序喜欢连接到 Microsoft 的网站以进行验证.

【讨论】:

    【解决方案4】:

    这是获取已安装的Excel版本的方法。

    Imports Microsoft.Office.Interop.Excel
    Public Class ExcelVersion
        Dim xl As Application
        Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handlers NextCmd.Click
           xl = New Application
           MsgBox xl.Version()
           xl.Quit()
        End Sub
    End Class
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-12
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多