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

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

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

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

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

# 実行例

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

```:比較フォルダ１
C:.
│  ファイル１.txt
│  ファイル２.txt
│  ファイル３.txt
│  ファイル４.txt
│  ファイル５.txt
│
├─サブフォルダ１
│      ファイル１.txt
│
└─サブフォルダ２
    │  ファイル４.txt
    │
    ├─サブフォルダ１
    │      ファイル１.txt
    │
    └─サブフォルダ２
        └─サブフォルダ１
            │  ファイル１.txt
            │
            └─サブフォルダ１
                    ファイル１.txt
```

```:比較フォルダ２
C:.
│  ファイル１.txt
│  ファイル２.txt
│  ファイル３.txt
│  ファイル４.txt
│  ファイル５.txt
│
├─サブフォルダ１
│      ファイル１.txt
│
└─サブフォルダ２
    │  ファイル４.txt
    │
    ├─サブフォルダ１
    │      ファイル１.txt
    │
    └─サブフォルダ２
        ├─サブフォルダ１
        │  └─サブフォルダ１
        │          ファイル１.txt
        │
        └─サブフォルダ２
                ファイル１.txt
```

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

## 実行時の様子
![5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292212/a819c8de-5ad8-3b25-0626-51d3e7dcfc75.gif)

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

## レポート出力結果
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292212/1c6044d8-5df9-3616-f797-1a0f3127733c.png)



# ソースコード
```vb: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
```


# 参考サイト
https://qiita.com/mima_ita/items/ac21c0588080e73fc458