【问题标题】:Batch file to compare versions of MSI file and Installed version用于比较 MSI 文件版本和已安装版本的批处理文件
【发布时间】:2014-12-18 09:03:37
【问题描述】:

我目前有一个安装脚本,仅在尚未安装产品时安装(通过检查应用程序的 EXE 是否存在),但我想更进一步,仅在以下情况下安装它MSI 版本比安装的版本新。尽管脚本可以很好地查询 MSI不需要总是更新。

我找不到任何可以让我获得 MSI 版本的东西,我看到 MSI 版本的唯一地方是当我查看文件属性 -> 详细信息 -> 主题行:产品 XYZ 10.2 .3.

为了检查安装的版本,我发现:

wmic datafile where name='c:\\windows\\system32\\notepad.exe' get version

返回两行,其中第二行是 10,2,3(使用逗号而不是小数)。

如果我使用:

wmic product where "name like 'Product XYZ%%'" get version

我得到了相同的结果,但采用了预期的十进制格式,但查询需要更长的时间才能运行。但无论哪种情况,我仍然需要弄清楚如何实际处理查询的结果。

使用 VBS 可能会更容易,我可以接受,只要我可以在现有的批处理文件中调用它并在我的批处理文件中处理 VBS 结果。

提前致谢! 布赖恩

【问题讨论】:

    标签: windows batch-file vbscript windows-installer version


    【解决方案1】:

    这显示了使用 findstr 提取特定信息的原理。

    @echo off
    
    If "%~1"=="" goto help
    If "%~1"=="/?" goto help
    If /i "%~1"=="/h" goto help
    If "%~1"=="-?" goto help
    If /i "%~1"=="-h" goto help
    
    set filepath=%~f1
    set  file=%filepath:\=\\%
    wmic datafile where name^="%file%" get version|findstr /i /v /c:"version"
    echo %errorlevel%
    goto finish
    
    :help
    Echo.
    Echo. FileVer
    Echo. -------
    Echo.
    Echo.    By David Candy 2013
    Echo.
    Echo. Purpose:
    Echo.
    Echo.    Reports the version number for an exe, dll, and similar files.
    Echo.
    Echo. Usage:
    Echo.
    Echo.    filever ^<executable file^>
    Echo.
    Echo.    filever [/h ^| -h ^| /? ^| -?]    Starts this help
    Echo.
    echo. Examples:
    Echo.
    Echo.    filever c:\windows\explorer.exe
    Echo.    filever "C:\Program Files\Windows NT\Accessories\wordpad.exe"
    Echo.    filever shell32.dll
    
    Echo.
    Echo.    For Help
    Echo.
    Echo.    filever 
    
    Echo.    filever /?
    Echo.
    
    :finish
    rem Pause if command double clicked
    If /i "%cmdcmdline:~0,6%"=="cmd /c" pause
    

    这表明使用 For

    set service=%1
    for /f "skip=1 tokens=1,2,3* delims= " %%a in ('sc getkeyname %service%') do echo %%c
    

    【讨论】:

    • 好的,第一部分工作得很好,并输出版本号(然后是一个空行和“0”(我假设的错误级别))。但是我很难弄清楚 FOR 语句。我试过修改它,但没有得到我想要的结果。如果我只是复制/粘贴您的版本,则 FOR 语句会在“0”之后的行上回显“服务”。如果我只运行 WMIC 命令: C:\>wmic datafile where name='c:\\application.exe' get version 这是输出: Version (line1) 1.2.456.78 (line2)
    • 对不起,不喜欢这个评论系统缺乏格式(或者我不明白)。我只是在寻找 FOR 语句以提取“1.2.456.78”并将其用作变量,然后我可以将其与 MSI 的静态值进行比较(因为我找不到类似的东西适用于MSI 文件)。不确定是否重要,但“1.2.456.78”的长度可能会发生变化,因为有时第 3 部分(“456”)只能是 1 位数字。
    【解决方案2】:

    这是一种使用makecab 的方法:

    ; @echo off
    ;;goto :end_help
    ;;setlocal DsiableDelayedExpansion
    ;;;
    ;;;
    ;;; fileinf /l list of full file paths separated with ;
    ;;; fileinf /f text file with a list of files to be processed ( one on each line )
    ;;; fileinf /? prints the help
    ;;;
    ;;:end_help
    
    ; REM Creating a Newline variable (the two blank lines are required!)
    ; set NLM=^
    
    
    ; set NL=^^^%NLM%%NLM%^%NLM%%NLM%
    ; if "%~1" equ "/?" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
    ; if "%~2" equ "" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
    ; setlocal enableDelayedExpansion
    ; if "%~1" equ "/l" (
    ;  set "_files=%~2"
    ;  echo !_files:;=%NL%!>"%TEMP%\file.paths"
    ;  set _process_file="%TEMP%\file.paths"
    ;  goto :get_info
    ; )
    
    ; if "%~1" equ "/f" if exist "%~2" (
    ;  set _process_file="%~2"
    ;  goto :get_info
    ; )
    
    ; echo incorect parameters & exit /b 1
    ; :get_info
    ; set "file_info="
    
    ; makecab /d InfFileName=%TEMP%\file.inf /d "DiskDirectory1=%TEMP%" /f "%~f0"  /f %_process_file% /v0>nul
    
    ; for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do (
    ;  set "file_info=%%f"
    ;  echo !file_info:,=%nl%!
    ; )
    
    ; endlocal
    ;endlocal
    ; del /q /f %TEMP%\file.inf 2>nul
    ; del /q /f %TEMP%\file.path 2>nul
    ; exit /b 0
    
    .set DoNotCopyFiles=on
    .set DestinationDir=;
    .set RptFileName=nul
    .set InfFooter=;
    .set InfHeader=;
    .Set ChecksumWidth=8
    .Set InfDiskLineFormat=;
    .Set Cabinet=off
    .Set Compress=off
    .Set GenerateInf=ON
    .Set InfDiskHeader=;
    .Set InfFileHeader=;
    .set InfCabinetHeader=;
    .Set InfFileLineFormat=",file:*file*,date:*date*,size:*size*,csum:*csum*,time:*time*,vern:*ver*,vers:*vers*,lang:*lang*"
    

    这里是一个例子,如果脚本被称为fileinfo.bat

    c:> fileinfo.bat /l C:\install.exe
        file:install.exe
        date:11/07/07
        size:562688
        csum:380ef239
        time:07:03:18a
        vern:9.0.21022.8
        vers:9.0.21022.8 built by: RTM
        lang:1033
    

    【讨论】:

      【解决方案3】:

      也许你可以改编这个脚本。 pver 变量是版本字符串,pname 告诉您名称。您可以使用 vbs 做更多事情,因为有一个以 Installer 对象开头的完整脚本引擎。抱歉格式化,还没有掌握SO。

      选项显式

      公共安装程序、fullmsg、comp、prod、a、fso、pname、ploc、pid、psorce、pcache、pver

      设置 fso = CreateObject("Scripting.FileSystemObject")

      设置 a = fso.CreateTextFile("prods.txt", True)

      ' 连接到 Windows Installer 对象 设置安装程序 = CreateObject("WindowsInstaller.Installer") a.writeline(“产品”) 错误继续下一步 对于 installer.products 中的每个产品

      pid = installer.productinfo (prod, "ProductID")

      pname = installer.productinfo (prod, "ProductName")

      pver = installer.productinfo (prod, "VersionString")

      psorce=installer.productinfo(prod, "InstallSource")

      ploc = installer.productinfo (prod, "InstallLocation")
      pcache = installer.productinfo(prod, "LocalPackage") a.writeline (prod & " " & pname & " Version " & pver & " 安装在 " & ploc & " from " & psorce & " 缓存在 " & pcache)

      下一个

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-21
        • 1970-01-01
        • 2012-10-15
        • 2017-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多