WinMergeのファイル比較結果の出力を自動化してみた


自動化の背景

当時300以上の設計書の差分を洗い出してマージを行うという業務を任され、設計書の比較及び比較結果の出力にWinMergeを用いていたが、ドキュメントの大半がExcelファイルであり、WinMergeの比較自体に時間がかかるため、自動化を検討

比較するにあたり、以下の作業をひたすら繰り返すのはなかなか大変だと思い、、、

  • 比較したいファイルを選択した状態で右クリックし、WinMergeを選択
  • 比較結果が表示されたら(Excelを比較する場合少し時間がかかる)、レポートの生成を押下
  • レポートの保存先を指定

作ったもの

  • VBScriptでWinMergeをコマンドラインで実行させることで自動化するスクリプト
  • 比較対象のフォルダを指定し、サブフォルダも含めたファイルを比較して、比較結果をhtm形式で出力
  • 同じフォルダ構成の同一名のファイルを比較対象

実行例

比較対象フォルダ

一例として、以下のフォルダ構成が若干異なる2つのフォルダを用意してスクリプトを実行させます。

比較フォルダ1
C:.
│  ファイル1.txt
│  ファイル2.txt
│  ファイル3.txt
│  ファイル4.txt
│  ファイル5.txt
│
├─サブフォルダ1
│      ファイル1.txt
│
└─サブフォルダ2
    │  ファイル4.txt
    │
    ├─サブフォルダ1
    │      ファイル1.txt
    │
    └─サブフォルダ2
        └─サブフォルダ1
            │  ファイル1.txt
            │
            └─サブフォルダ1
                    ファイル1.txt
比較フォルダ2
C:.
│  ファイル1.txt
│  ファイル2.txt
│  ファイル3.txt
│  ファイル4.txt
│  ファイル5.txt
│
├─サブフォルダ1
│      ファイル1.txt
│
└─サブフォルダ2
    │  ファイル4.txt
    │
    ├─サブフォルダ1
    │      ファイル1.txt
    │
    └─サブフォルダ2
        ├─サブフォルダ1
        │  └─サブフォルダ1
        │          ファイル1.txt
        │
        └─サブフォルダ2
                ファイル1.txt

使い方

WinMerge比較結果出力.vbs 比較対象フォルダ1 比較対象フォルダ2 レポート出力先

実行時の様子

コマンドプロンプトで実行して、実行後にtreeコマンドでレポート出力先のフォルダ構成を確認し、同一フォルダ構成のファイルのみ比較結果が出力されるのを確認できました。

レポート出力結果

ソースコード

WinMerge比較結果出力.vbs
'*********************************************************
'[概要]
' 指定したフォルダから、サブフォルダも含めてファイルを比較して、比較結果をhtm形式で出力します
' 同じフォルダ構成の同一名のファイルを対象とします
'
'[使い方]
' WinMerge比較結果出力.vbs 比較対象フォルダ1 比較対象フォルダ2 レポート出力先
'*********************************************************

Dim WshShell: Set WshShell=Wscript.CreateObject("Wscript.Shell")
Dim objFileSys: Set objFileSys = WScript.CreateObject("Scripting.FileSystemObject")
Dim objParam: Set objParam = WScript.Arguments
Dim lngCnt: lngCnt = Len(objParam(0))

'WinMergeのインストールディレクトリに移動(PATHを通しているのであれば不要)
WshShell.CurrentDirectory = "C:\Program Files\WinMerge"

'WinMerge実行処理呼び出し
call execWinMerge(objParam(0), objParam(1), objParam(2))

msgbox "end"

'*********************************************************
'[概要]
' WinMerge実行プロシージャ
' 
'[引数]
' inputFilePath1:比較対象フォルダ1 
' inputFilePath2:比較対象フォルダ2 
' outputFilePath:レポート出力先
'*********************************************************
Sub execWinMerge(inputFilePath1,inputFilePath2, outputFilePath)

    'レポート出力先のフォルダ作成
    If not objFileSys.FolderExists(outputFilePath) Then
        objFileSys.CreateFolder(outputFilePath)
    End If

    'WinMerge実行
    For Each file In objFileSys.GetFolder(inputFilePath1).Files
        '比較対象ファイルの存在判定
        If objFileSys.FileExists(inputFilePath2 & "\" & file.Name) Then
            '同一ファイルが存在する場合にWinMerge実行
            inputFile1 =  inputFilePath1 & "\" & file.Name
            inputFile2 = inputFilePath2 & "\" & file.Name
            outputReport = outputFilePath & "\" & objFileSys.GetBaseName(file) & ".htm"
            WshShell.Run("WinMergeU.exe /e " & """" & inputFile1 & """" & " " & """" & inputFile2 & """" & " /minimize /noninteractive /u /or " & """" & outputReport & """")
        End If
    Next

    'サブフォルダに対してもWinMergeを実行
    For Each subfolder in objFileSys.GetFolder(inputFilePath1).Subfolders 
        If subfolder.Name <> "" Then
            'サブフォルダが存在する場合は、再帰処理を実行
            strSubfolderPath = Mid(subfolder, lngCnt + 2) 
            inputFilePath2 = objParam(1) & "\" & strSubfolderPath
            outputFilePath = objParam(2) & "\" & strSubfolderPath
            call execWinMerge(subfolder, inputFilePath2, outputFilePath)
        End If
    Next
End Sub

参考サイト