【入門編】【関連付け起動情報の検証】Assoc および Ftype 情報をスクリプト内から取得し特定拡張子の既定アプリ判定 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

こんにちは!VBScriptの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩踏み出し、「Windowsの裏側を自分の手足のように動かしたい」と思っているあなたなら、きっとこの扉を開けるワクワク感を感じていることでしょう。

今回は、業務自動化の現場で地味ながら「知っていると神になれる」超実用的なテーマ、【関連付け起動情報の検証】について解説します。

「特定の拡張子(`.pdf`や`.csv`など)が、意図したアプリで開かれるか事前に知りたい」
「変なアプリに関連付けられていて、スクリプトからの自動処理が暴発するのを防ぎたい」

そんな現場の絶望を未然に防ぐための診断コードを、一緒に紐解いていきましょう。ここをクリアすれば、WSH(Windows Script Host)を使った環境診断の基本はバッチリですよ!

なぜ「関連付け」をスクリプトで検証する必要があるのか?

業務でVBScriptを使ってファイルを開くとき、お馴染みなのが `WshShell.Run` や `Shell.Application` ですよね。

Dim wsh
Set wsh = CreateObject(“WScript.Shell”)
wsh.Run “report.pdf” ‘ ← これでPDFが開く

一見、とてもスマートです。しかし、エンジニアとして場数を踏むと、こんな恐怖に直面します。

  • 「あれ? このPC、PDFの既定アプリがブラウザになっておかしな挙動をするぞ…」
  • 「別部署のPCで実行したら、`.csv` が謎のテキストエディタに関連付けられていて処理が崩壊した」

VBScript自体には「このファイルはこのアプリで開く」という直接的な制御権はありません。すべてWindowsの「関連付け(Association)」任せです。だからこそ、「実行する前に、いまこの拡張子はどういう状態になっているのか?」をスクリプト自身に診断させる必要があるのです。

Windowsの心臓部:「Assoc」と「Ftype」の仕組み

Windowsがファイルの関連付けを管理している仕組み、実はとてもシンプルです。コマンドプロンプトでおなじみの2つのコマンドが鍵を握っています。

1. `assoc`(アソシエーション): 拡張子(`.txt` や `.pdf`)と「ファイルタイプ(filetype)」を紐付けるテーブル。
2. `ftype`(エフタイプ): ファイルタイプが「実際にどの実行ファイル(`.exe`)で開かれるか」を定義するテーブル。

例えば、コマンドプロンプトで `assoc .txt` と叩くと `.txt=txtfile` と返ってきます。次に `ftype txtfile` と叩くと `txtfile=C:\Windows\System32\NOTEPAD.EXE %1` のように返ってくる。この2段階のステップを経て、Windowsはアプリを起動しているのです。

VBScriptからこの情報をスマートに取得できれば、環境に依存しない堅牢な自動化スクリプトが作れます。

実践! 拡張子の関連付けを完全診断するVBScript

それでは、実際のコードを見てみましょう。
今回は、指定した拡張子の「関連付け先」と「実体の実行ファイルパス」を暴き出す診断スクリプトを用意しました。

メモ帳(Notepad)に貼り付けて、拡張子を `.vbs` にして保存し、実行してみてください。

‘ =====================================================================
‘ 拡張子関連付け診断スクリプト (CheckAssociation.vbs)

‘ 【使い方】
‘ 診断したい拡張子をtargetExt変数に代入して実行してください。
‘ =====================================================================

Option Explicit

Dim targetExt
targetExt = “.pdf” ‘ ←ここに調べたい拡張子を入れてね(例: .csv, .xlsx, .pdf)

Call DiagnoseFileAssociation(targetExt)

Sub DiagnoseFileAssociation(ext)
Dim wsh, execObj, assocResult, ftypeKey, ftypeResult
Dim fso

Set wsh = CreateObject(“WScript.Shell”)
Set fso = CreateObject(“Scripting.FileSystemObject”)

WScript.Echo “=== 【VBScript 診断レポート】 ===” & vbCrLf & _
“対象拡張子: ” & ext

‘ 1. Assocコマンドを実行してファイルタイプを取得
‘ 例: .pdf -> Acrobat.Document.DC など
Set execObj = wsh.Exec(“cmd /c assoc ” & ext)
assocResult = Trim(execObj.StdOut.ReadAll())

If assocResult = “” Then
WScript.Echo “【警告】この拡張子(” & ext & “)は、いかなるファイルタイプとも関連付けられていません!”
Exit Sub
End If

WScript.Echo “[Assoc情報] ” & assocResult

‘ Assocの結果は “.ext=filetype” の形式なので、”=”以降を抽出
Dim delimiterPos
delimiterPos = InStr(assocResult, “=”)
If delimiterPos > 0 Then
ftypeKey = Mid(assocResult, delimiterPos + 1)

‘ 2. Ftypeコマンドを実行して起動コマンドを取得
‘ 例: Acrobat.Document.DC -> “C:\Program Files\…\AcroRd32.exe” “%1”
Set execObj = wsh.Exec(“cmd /c ftype ” & ftypeKey)
ftypeResult = Trim(execObj.StdOut.ReadAll())

If ftypeResult = “” Then
WScript.Echo “【注意】ファイルタイプ(” & ftypeKey & “)に対するFtypeが定義されていません。”
Else
WScript.Echo “[Ftype情報] ” & ftypeResult

‘ おまけ:実行ファイルのパスが存在するかチェックしてみる
‘ (※ftypeResultには引数や引用符が含まれるため、簡易的に先頭のパスを抽出)
Dim appPath
appPath = ExtractExecutablePath(ftypeResult)

If appPath <> “” And fso.FileExists(appPath) Then
WScript.Echo “【判定】正常: 関連付けられたアプリケーションは実在します -> ” & appPath
ElseIf appPath <> “” Then
WScript.Echo “【危険】関連付けられたアプリのパスが見つかりません(アンインストールされた可能性) -> ” & appPath
End If
End If
End If

WScript.Echo “========================================”
End Sub

‘ 補助関数: ftypeの出力結果から実行ファイルのパス(.exe)を抜き出す極秘テクニック
Function ExtractExecutablePath(ftypeStr)
Dim cleanStr
cleanStr = ftypeStr

‘ “=” を削除
If InStr(cleanStr, “=”) > 0 Then
cleanStr = Trim(Mid(cleanStr, InStr(cleanStr, “=”) + 1))
End If

‘ ダブルクォーテーションで囲まれている場合を考慮
If Left(cleanStr, 1) = “””” Then
Dim secondQuote
secondQuote = InStr(2, cleanStr, “”””)
If secondQuote > 0 Then
ExtractExecutablePath = Mid(cleanStr, 2, secondQuote – 2)
Exit Function
End If
End If

‘ 囲まれていない場合は最初のスペースまでをパスとみなす
Dim spacePos
spacePos = InStr(cleanStr, ” “)
If spacePos > 0 Then
ExtractExecutablePath = Left(cleanStr, spacePos – 1)
Else
ExtractExecutablePath = cleanStr
End If
End Function

コードのポイントと、陥りやすい罠

このコードには、現場で培った「VBScriptを安定動作させるための知見」がいくつか詰まっています。初学者がハマりやすいポイントを解説しておきますね。

1. `WshShell.Run` ではなく `WshShell.Exec` を使う理由

コマンドプロンプトの出力をVBScript側で受け取るために `WshShell.Exec` を使用しています。`Run` だとコンソール画面がピョコっと出てしまったり、標準出力をキャプチャできません。
`Exec` を使うことで、コマンドの実行結果(`StdOut.ReadAll`)を文字列として完全に変数に回収できるのです。

2. パス抽出の罠(スペースとダブルクォーテーション)

`ftype` コマンドが返す文字列は、アプリのインストールパスにスペースが含まれるため、通常 `”C:\Program Files\…” “%1″` のようにダブルクォーテーションで囲まれています。
これをそのままファイル存在確認(`FileExists`)に投げると、パスが無効だと判定されてエラーになります。
今回のコードにある `ExtractExecutablePath` 関数は、このダブルクォーテーションや引数(`%1`など)を綺麗に剥ぎ取り、純粋な `.exe` のパスだけを抽出する職人芸的な処理を行っています。

先輩エンジニアからのアドバイス

いかがでしたか? `assoc` や `ftype` といったWindowsの根本的な仕組みをVBScriptから叩くことで、単なる「ファイルをポーンと開くスクリプト」から、「実行環境の健全性まで診断できるインテリジェントな自動化ツール」へと進化させることができます。

「他人のPCで動かしたら謎のエラーで止まった…」という悲劇を生まないために、スクリプトの冒頭でこうした関連付け検証を挟むのは、プロのエンジニアとしても非常にスマートなアプローチです。

ここをクリアできれば、WSHやOSのコマンド連携の基礎はもうバッチリ。ぜひ自分の業務環境で試して、自動化の引き出しをさらに広げてくださいね!

タイトルとURLをコピーしました