Edited at

【BAT】Microsoft Visual C++ 再頒布可能パッケージのインストール確認


はじめに

WinFormsでChromiumブラウザコンポーネント(CefSharp)を使ってみる」の記事に書いたのですが、CefSharpを使うには、「Visual Studio C++ 2015 redistributables(再頒布可能パッケージ)」以上が必要となります。

ユーザーにCefSharpを使用したアプリケーションを配布する際、オフライン向けのインストール用バッチを作成することにしました。


インストール済の確認

今回の.NETアプリケーションはAnyCPUとしているので、32bit(x86) か 64bit(x64) かの判断も行います。

また、2015以上が既にインストールされている場合はインストール済みとします。


  • Visual Studio C++ 2015 Redistributable (x86)

  • Visual Studio C++ 2015 Redistributable (x64)

インストール済みかの判断は、レジストリのアンインストール情報を取得します。

CPU
レジストリのアンインストール情報

32bit
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

64bit
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

vc_redistフォルダ配下にVisual Studio C++ 2015 redistributables(再頒布可能パッケージ)を配置しておきます。


  • vc_redist.x86.exe

  • vc_redist.x64.exe


注意

2012からRedistributable (x99) 形式で統一されているのですが、それより前は統一されていませんでした。

今回は、2015以上インストール済みかなので Redistributable (x99)形式で抽出しています。

また、2015以上かどうかはバージョン番号ではなく年(2015)で判断しています。最初はメジャーバージョンで判断してたのですが、2015と2017は同じ14だった。

CPU
レジストリのアンインストール情報

32bit
Visual Studio C++ 2005 Redistributable

64bit
Visual Studio C++ 2005 Redistributable (x64)

32bit
Visual Studio C++ 2008 Redistributable - x86 9.0.xxxxx

64bit
Visual Studio C++ 2008 Redistributable - x64 9.0.xxxxx

32bit
Visual Studio C++ 2010 x86 Redistributable - 10.0.xxxxx

64bit
Visual Studio C++ 2010 x64 Redistributable - 10.0.xxxxx

32bit
Visual Studio C++ 2012 Redistributable (x86) - 11.0.xxxxx

64bit
Visual Studio C++ 2012 Redistributable (x64) - 11.0.xxxxx

32bit
Visual Studio C++ 2013 Redistributable (x86) - 12.0.xxxxx

64bit
Visual Studio C++ 2013 Redistributable (x64) - 12.0.xxxxx

32bit
Visual Studio C++ 2015 Redistributable (x86) - 14.0.xxxxx

64bit
Visual Studio C++ 2015 Redistributable (x64) - 14.0.xxxxx

32bit
Visual Studio C++ 2017 Redistributable (x86) - 14.16.xxxxx

64bit
Visual Studio C++ 2017 Redistributable (x64) - 14.16.xxxxx


バッチ版

最初にバッチのみで作成したのですが、レジストリ情報の検索(REG QUERYコマンド)が遅いんですよね。

自分のPCは確かに開発用にいろいろインストールされているのですが、インストール済みの判定だけで1分以上かかります。


Install.bat

@echo off

cd /d %~dp0
set vcInstall=0
set vcVersion=2015

setlocal enabledelayedexpansion

echo Microsoft Visual C++ 再頒布可能パッケージ 2015のインストール

if "%PROCESSOR_ARCHITECTURE%" equ "x86" (
call :DetectVC x86 HKEY_LOCAL_MACHINE\Software
if !vcInstall!==0 start /wait vc_redist\vc_redist.x86.exe
)
if "%PROCESSOR_ARCHITECTURE%" equ "AMD64" (
call :DetectVC x64 HKEY_LOCAL_MACHINE\Software\Wow6432Node
if !vcInstall!==0 start /wait vc_redist\vc_redist.x64.exe
)

endlocal
exit /b

REM -------------------------------------------------------
REM Microsoft Visual C++ 再頒布可能パッケージ 2015以上の検出
REM -------------------------------------------------------
:DetectVC
set "vcfindname=Redistributable (%1)"

for /f "TOKENS=1,2,*" %%A in ('REG QUERY "%2\Microsoft\Windows\CurrentVersion\Uninstall" /s ^| find "DisplayName"') do (
echo %%C | find "%vcfindname%" >NUL
if not ERRORLEVEL 1 (
set str=%%C
set vcver=!str:~21,4!
set vcver=!vcver:ab=0!
if !vcver! geq %vcVersion% (
set vcInstall=1
)
)
)

if %vcInstall%==1 (
echo.
echo Microsoft Visual C++ 再頒布可能パッケージ 2015以上インストール済み
) else (
echo.
echo Microsoft Visual C++ 再頒布可能パッケージ 2015以上未インストール
)

exit /b



VBScript版

VBScriptにしたら数秒でインストール済みの判定ができました。

vc_redistフォルダ配下にCheckVCRedist.vbsを配置します。


CheckVCRedist.vbs

Option Explicit

'On Error Resume Next
Const HKEY_LOCAL_MACHINE = &H80000002
Const SubKeyName = "Microsoft\Windows\CurrentVersion\Uninstall\"
Const VCVersion = 2015

Dim WshShell, arch, reg, firstkey, keys, key, ret, display_name
Set WshShell = WScript.CreateObject("WScript.Shell")
arch = WshShell.Environment("Process").Item("PROCESSOR_ARCHITECTURE")

If arch = "x86" Then
firstkey = "SOFTWARE\"
Else
firstkey = "SOFTWARE\Wow6432Node\"
arch = "x64"
End If

Set reg = CreateObject("WbemScripting.SWbemLocator").ConnectServer(, "root\default").Get("StdRegProv")
reg.EnumKey HKEY_LOCAL_MACHINE, firstkey & SubKeyName, keys

For Each key In keys
display_name = ""
ret = reg.GetStringValue(HKEY_LOCAL_MACHINE, firstkey & SubKeyName & key, "DisplayName", display_name)
If Instr(display_name, "Redistributable (" & arch & ")") > 0 Then
If CInt(Mid(display_name, 22, 4)) >= VCVersion Then
Wscript.Quit(1)
End If
End If
Next

Wscript.Quit(0)


検出の内容を「cscript //nologo vc_redist\CheckVCRedist.vbs」に変更します。


Install.bat

@echo off

cd /d %~dp0
set vcInstall=0
set vcVersion=2015

echo Microsoft Visual C++ 再頒布可能パッケージ 2015のインストール
call :DetectVC

if "%PROCESSOR_ARCHITECTURE%" equ "x86" (
if %vcInstall%==0 start /wait vc_redist\vc_redist.x86.exe
)
if "%PROCESSOR_ARCHITECTURE%" equ "AMD64" (
if %vcInstall%==0 start /wait vc_redist\vc_redist.x64.exe
)

exit /b

REM -------------------------------------------------------
REM Microsoft Visual C++ 再頒布可能パッケージ 2015以上の検出
REM -------------------------------------------------------
:DetectVC

cscript //nologo vc_redist\CheckVCRedist.vbs

set vcInstall=%ERRORLEVEL%

if %vcInstall%==1 (
echo.
echo Microsoft Visual C++ 再頒布可能パッケージ 2015以上インストール済み
) else (
echo.
echo Microsoft Visual C++ 再頒布可能パッケージ 2015以上未インストール
)

exit /b



最後に

REG QUERYコマンドがこんなに遅いとは、インストールは最初の1回だけとはいえユーザーが不安になるレベルの遅さなの、VBScript版が速くて良かった。


参照