【问题标题】:How to Retrieve a File's "Product Version" in VBScript如何在 VBScript 中检索文件的“产品版本”
【发布时间】:2023-03-16 05:33:01
【问题描述】:

我有一个 VBScript,它检查远程计算机上目录中是否存在文件。我正在寻找所述文件的“产品版本”(NOT文件版本”),但我似乎无法弄清楚了解如何在 VBScript 中做到这一点。

我目前正在使用Scripting.FileSystemObject 来检查文件是否存在。

谢谢。

【问题讨论】:

标签: vbscript


【解决方案1】:

我使用了一个对上一个示例稍作修改的函数。该函数获取路径和文件名并返回“产品版本”

Function GetProductVersion (sFilePath, sProgram)
Dim FSO,objShell, objFolder, objFolderItem, i 
Set FSO = CreateObject("Scripting.FileSystemObject")
If FSO.FileExists(sFilePath & "\" & sProgram) Then
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.Namespace(sFilePath)
    Set objFolderItem = objFolder.ParseName(sProgram)
    Dim arrHeaders(300)
    For i = 0 To 300
        arrHeaders(i) = objFolder.GetDetailsOf(objFolder.Items, i)
        'WScript.Echo i &"- " & arrHeaders(i) & ": " & objFolder.GetDetailsOf(objFolderItem, i)
        If lcase(arrHeaders(i))= "product version" Then
            GetProductVersion= objFolder.GetDetailsOf(objFolderItem, i)
            Exit For
        End If
    Next
End If
End Function

我发现属性的位置在 XP 和 Vista 中偶尔会发生变化(不知道为什么),所以我寻找“产品版本”属性并在找到后退出循环。注释掉的行将显示所有属性和一个值(如果可用)

【讨论】:

  • 您没有创建 FSO 对象以在您的函数中使用它,您必须在函数的第 2 行之后添加“Set FSO=CreateObject("Scripting.FileSystemObject")”
  • 为什么是 300?用 (2 ^ 15) - 1 是不是更好,这是最大的整数值?
  • 代码可以使用一些明显的改进。 1.不需要数组。只需将其替换为单个变量即可。 2.将Items传递给GetDetailsOf是没有意义的。该参数“必须是 FolderItem 对象”,尽管显然如果您传递任何无效值,它会返回标题名称。只需在第一次调用中传递“”。 3.不需要FSO。如果目录或文件不存在,Namespace() 或 ParseName() 将返回 Nothing,因此您可以检查它以防止错误的路径/文件名(如 GetDetailsOf 当前文档中所示)。
【解决方案2】:

您可以使用Shell.Namespace 获取文件上的extended properties,其中之一是产品版本。 GetDetailsOf 函数应该可以工作。您可以使用以下代码进行测试以了解想法:

Dim fillAttributes(300)

Set shell = CreateObject("Shell.Application")
Set folder = shell.Namespace("C:\Windows")

Set file = folder.ParseName("notepad.exe")

For i = 0 to 299
    Wscript.Echo i & vbtab & fillAttributes(i) _
        & ": " & folder.GetDetailsOf(file, i) 
Next

需要注意的一点:

文件的扩展属性因 Windows 版本而异。因此,产品版本索引号会根据您使用的 Windows 版本而变化。您可以使用上面的代码来确定它们是什么。根据我的测试,我认为它们如下:

  • Window XP - 39
  • Windows Vista - 252
  • Windows 7 - 268
  • Windows 2008 R2 SP1 - 271
  • Windows 2012 R2 - 285

您可能还会发现以下post 很有帮助。

【讨论】:

  • 您的代码的第一行“Dim fillAttributes(300)”没有在您的脚本中添加任何内容。您必须将“fillAttributes(i)”替换为“folder.GetDetailsOf(folder.Items,i)”
【解决方案3】:
' must explicitly declare all variables
Option Explicit
' declare global variables
Dim aFileFullPath, aDetail
' set global variables
aFileFullPath = "C:\Windows\Notepad.exe"
aDetail = "Product Version"
' display a message with file location and file detail
WScript.Echo ("File location: " & vbTab & aFileFullPath & vbNewLine & _
aDetail & ": " & vbTab & fGetFileDetail(aFileFullPath, aDetail))
' make global variable happy. set them free
Set aFileFullPath = Nothing
Set aDetail = Nothing
' get file detail function. created by Stefan Arhip on 20111026 1000
Function fGetFileDetail(aFileFullPath, aDetail)
' declare local variables
Dim pvShell, pvFileSystemObject, pvFolderName, pvFileName, pvFolder, pvFile, i
' set object to work with files
Set pvFileSystemObject = CreateObject("Scripting.FileSystemObject")
' check if aFileFullPath provided exists
If pvFileSystemObject.FileExists(aFileFullPath) Then
' extract only folder & file from aFileFullPath
pvFolderName = pvFileSystemObject.GetFile(aFileFullPath).ParentFolder
pvFileName = pvFileSystemObject.GetFile(aFileFullPath).Name
' set object to work with file details
Set pvShell = CreateObject("Shell.Application")
Set pvFolder = pvShell.Namespace(pvFolderName)
Set pvFile = pvFolder.ParseName(pvFileName)
' in case detail is not detected...
fGetFileDetail = "Detail not detected"
' parse 400 details for given file
For i = 0 To 399
' if desired detail name is found, set function result to detail value
If uCase(pvFolder.GetDetailsOf(pvFolder.Items, i)) = uCase(aDetail) Then
fGetFileDetail = pvFolder.GetDetailsOf(pvFile, i)
End If
Next
' if aFileFullPath provided do not exists
Else
fGetFileDetail = "File not found"
End If
' make local variable happy. set them free
Set pvShell = Nothing
Set pvFileSystemObject = Nothing
Set pvFolderName = Nothing
Set pvFileName = Nothing
Set pvFolder = Nothing
Set pvFile = Nothing
Set i = Nothing
End Function

【讨论】:

    【解决方案4】:
    Wscript.Echo CreateObject("Scripting.FileSystemObject").GetFileVersion("C:\Windows\notepad.exe")
    

    【讨论】:

    • OP 说的是产品版本,而不是文件版本。它们不是一回事。
    • 这在技术上并不正确,但它很好地满足了我的目的,并且比所有其他答案都简洁得多。
    【解决方案5】:

    产品版本可以直接用ExtendedProperty方法获取。

    function GetProductVersion(Path)
        dim shell, file
        set shell = CreateObject("Shell.Application")
        const ssfDesktop = 0
        set file = shell.Namespace(ssfDesktop).ParseName(Path)
        if not (file is nothing) then
            GetProductVersion = _
                file.ExtendedProperty("System.Software.ProductVersion")
        end if
    end function
    

    与几个较旧的答案相比,

    • 这不需要使用 GetDetailsOf 遍历未知或任意数量的列。
    • 这使用属性的规范名称,而不是显示名称。也可以使用 FMTID 和 PID:"{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 8"
    • 这避免了将路径拆分为目录和名称的需要,从根(桌面)命名空间开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      相关资源
      最近更新 更多