Windowsで特定のファイルのバージョンを取得したい

とある事情であるディレクトリの下にある特定のファイルについてバージョンを取得することになった

バージョンを取得する

  • Support Toolsやフリーのツールが有るようですがいちいち入れるのが面倒なのでPowerShellでやることにした
    • ググって試行錯誤して下のやり方で出来ました
(Get-ItemProperty D:\foo\bar\hogehoge.dll).VersionInfo.FileVersion

ファイルを探す

  • hogehoge.dllは一つではないというかたくさんあるので手作業じゃ探せません。
    • Windowsにはfind.exeがついてるのだがこれは違うのでダメ!
    • git bashについていたfind.exeを使ってみたらなんかエラーで落ちる(>_<)
    • またしてもPowerShell
ls -r | where { $_.Name -match "hogehoge.dll" } | select-object fullname > out.txt
  • select-object fullnameを付けないとフルパスで出ませんでした。

全部やる

  • ファイルが沢山あるので先にファイルリスト作ってしまいました
    • これを元にファイルバージョンを取得していけば良さそうです
    • まあ、本当は該当ファイルを1行取ったらすぐにバージョンを評価すれば途中でも内容がわかっていいんでしょうけど・・・
$FILES = Get-Content out.txt
foreach($F in $FILES) {
    Write-Host -NoNewLine $F.Trim()", "
    (Get-ItemProperty $F).VersionInfo.FileVersion
}
  • Write-Host -NoNewLineを使って改行なしの出力を指定ます。(Linuxなんかだとecho -nでできて楽だけど)
  • .Trim()を使って変な空白を除去して、", "を付けてカンマ区切りで出しました。

スクリプトでやる

  • このスクリプトをgetver.ps1とかやって実行するとエラーになります。
    • 設定を変えて実行できるようにします。
PS> Set-ExecutionPolicy RemoteSigned

今回はこれでおしまい!

追記

長いファイル名は途中で「...」で省略されてしまう。

PS> D:\foo\bar\hogehoge.dll
PS> D:\foo\bar\aaa\bbb\ccc\ddd\eee\fff\hog...
  • こんな感じで切れる。
  • 検証するためにPowerShell ISEで実行すると出る。
PS> D:\foo\bar\hogehoge.dll
PS> D:\foo\bar\aaa\bbb\ccc\ddd\eee\fff\hogehoge.dll
  • どうやらコンソールの横幅に依存していた模様
    • コンソールの「プロパティ」から、「レイアウト」タブを選択、「画面バッファーのサイズ」の中の「幅」をデフォルト値(120)から少し大きく(200)したらちゃんと出るようになりました。
      • もっとスマートな解決策はありそうだけどとりあえず今回は欲しいデータが取れたのでよしとしよう。

Write-Hostが実は標準出力じゃなかった

  • 標準出力にはバージョンしか出て無かった。とほほ。
    • 標準出力への出力を1回で行うように修正。
    • これが元のコード。
$FILES = Get-Content out.txt
foreach($F in $FILES) {
    Write-Host -NoNewLine $F.Trim()", "
    (Get-ItemProperty $F).VersionInfo.FileVersion
}

$FILES = Get-Content out.txt
foreach($F in $FILES) {
    $V = (Get-ItemProperty $F).VersionInfo.FileVersion
    $S = """" + $F.Trim() + """, """ + $V + """"
    Write-Output $S
}
  • Write-Hostの代わりにWrite-Outputを使うようにしてます。
  • ついでにダブルコーテーションでくくるようにしておきました。