銀河鉄道

【PowerShell】WinMergeでファイルを自動比較&HTMLレポート出力する

サムネイル
[PowerShell]Auto DiffHTML Output

指定フォルダ内にあるファイルを自動比較&HTMLレポートを出力する

# --- 設定 ---
$root = Split-Path -Parent $MyInvocation.MyCommand.Path
$exe = Join-Path $root 'WinMergeU.exe'
$src = Join-Path $root '旧ファイル'
$dst = Join-Path $root '新ファイル'
$out = Join-Path $root 'レポート'

if (!(Test-Path $out)) { New-Item -ItemType Directory -Path $out | Out-Null }

# --- WinMerge CLIで全ファイル比較 ---
Get-ChildItem $dst -File | ForEach-Object {
    $name = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
    $report = "$out\Diff_$name.html"
    if (Test-Path $report) { Write-Host "Skip: $name"; return }

    $srcFile = Get-ChildItem $src -File | Where-Object {
        [System.IO.Path]::GetFileNameWithoutExtension($_.Name) -eq $name
    }

    if ($srcFile) {
        & $exe /r /e /xq /ul /ur /minimize /or $report $_.FullName $srcFile.FullName
        Write-Host "✔ $name: compared."
    } else {
        Write-Host "✖ $name: not found in SRC."
    }
}
Write-Host "✅ All comparisons done."

やってることは、これのPowerShell版

コマンドで何してる?

& $exe /r /e /xq /ul /ur /minimize /or $report $_.FullName $srcFile.FullName

各スイッチの意味

オプション意味補足
/r再帰的にフォルダ内を比較サブフォルダも含めて比較する(Recursive)
/e既存のWinMergeウィンドウを使わず、新しいインスタンスで実行バッチ処理で使うと安全(既存ウィンドウに干渉しない)
/xq終了時に自動で閉じる“Exit Quietly”=比較が終わったら自動終了(UI出さない)
/ul左側を「読み取り専用」に設定左側(旧ファイル)を編集不可にする
/ur右側を「読み取り専用」に設定右側(新ファイル)も編集不可にする
/minimize最小化して起動GUIが出ても邪魔にならへんように
/or <file>HTMLレポート出力“Output Report” の略で、指定ファイルに比較結果をHTML形式で出力する

ここでやっていること

「WinMergeをGUIなし(自動)で起動して、旧フォルダと新フォルダの同名ファイルを比較 → 結果をHTMLで出力 → 終わったら閉じる」

$src$dst を比べて、
同じ名前のファイルがあったら差分レポート(Diff_ファイル名.html)を自動で出力する構成。

$MyInvocation.MyCommand.Path

PowerShell スクリプト自身のファイルパスを取得するための変数。
つまり、「このスクリプトファイルがどこにあるか」を正確に知ることができる。

たとえば

この変数は、実行中のスクリプトが置かれている場所(フルパス)を返す。

例:

# ファイル: C:\Tools\Compare\run.ps1
$path = $MyInvocation.MyCommand.Path
Write-Host $path

出力結果:

C:\Tools\Compare\run.ps1

これが「この ps1 ファイル自身の場所」。

よくある使い方

1. スクリプトと同じフォルダにあるファイルを扱う

$root = Split-Path -Parent $MyInvocation.MyCommand.Path
$exe  = Join-Path $root 'WinMergeU.exe'

スクリプトと同じフォルダの WinMergeU.exe を自動的に参照できる。

2. 他フォルダを相対パスで参照する

$logDir = Join-Path $root 'logs'

スクリプトの場所を起点に logs フォルダを指定できる。

3. どこから実行しても安定する

PowerShell では「実行フォルダ」と「スクリプトの格納フォルダ」が異なることがあるので、相対パスで書くとズレる可能性あり。
$MyInvocation.MyCommand.Path を使えば常に「スクリプトのある場所」を基準にできる。

よくある間違い

  • $PSScriptRoot も似ているが、コンソール上で直接実行した場合は空になることがある。
  • $MyInvocation.MyCommand.Path はファイル実行でもモジュール化でも常に安定して動作する。

まとめ

目的推奨変数備考
スクリプト自身のパスが欲しい$MyInvocation.MyCommand.Path常に確実
スクリプトのフォルダ(親ディレクトリ)Split-Path -Parent $MyInvocation.MyCommand.Path実運用ではこれをよく使用
モジュールや関数内での相対参照$PSScriptRoot特定条件下でのみ使用可

このように、次の行のように書くのが最も安定した設計。

$root = Split-Path -Parent $MyInvocation.MyCommand.Path

スクリプトがどの環境から実行されても、常に同じ基準フォルダで処理できる。

著者

author
月うさぎ

編集後記:
この記事の内容がベストではないかもしれません。

記事一覧