CodeZine(コードジン)

特集ページ一覧

Visual Studio .NETにdiff支援機能を追加する

マクロによるファイル比較ツールとの連携

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2005/05/13 00:00

開発時には、2つのファイルの変更箇所を比較したいということがよくあります。そういう時には、diffコマンドが便利なのですが、Visual Studio .NETにはなぜかそれがありません。マクロによってその問題を手軽に解決してみます。

はじめに

 ソースコードを書いている開発時には、いろいろなバージョンのファイルができあがるため、両者間の差分を取って変更箇所を確かめたいということがよくあります。しかしながら、Visual Studio .NETのIDE環境において、標準のメニューコマンドには、この機能が見当たりません。

 通常、このようなケースでは「diff」という、Unix環境では定番のツールを使用します(Win32版の「diff.exe」もあります)。Windowsでは、これを模した「WinDiff」というGUIツールが、Visual StudioやResource Kitなどに付属しています。

diff(Win32版)
diff(Win32版)

 しかし、これらを使うには、その都度、

  1. デスクトップに戻って、
  2. アプリケーションを起動し、
  3. 比較するファイルを選択する

 というような作業を繰り返さなければならず、かなり面倒です。

 この問題を楽にするための小さなVisual Studio .NETマクロを紹介します。

対象読者

 Visual Studio 2002以上を対象にしています。

必要な環境

 Visual Studio 2002が必要です。2003では検証していませんが、大丈夫と思います。

マクロとは

 マクロは操作の手順を記述して、定型作業を自動化するための機能です。ExcelのVBAなどと同様、Visual StudioにもVBAのようなものがついています。ただし、Visual Studioの場合、Visual Basic.NETで記述します。

今回作成するマクロの概要

 WinDiffはGUIツールですが、コマンドプロンプトから起動できます。2つのファイルを比較する場合、起動オプションとして、比較する2つのファイルパスを与えてやるだけです。この例では「C:\WinDiff.Exe」というパスにインストールされていると想定します。

コマンドプロンプトからの起動
>C:\WinDiff.exe "c:\file1.txt" "c:\file2.txt"

 このことから、マクロの設計としては、以下のようになります。

  1. ソリューションエクスプローラで選択中の2つのファイルパス情報を取得
  2. 2つのファイルパスを引数としたコマンド文字列を作成し「WinDiff.exe」のプロセスを起動する

準備

 [ツール]→[マクロ]→[マクロIDE...]を実行し、マクロIDEを起動します。プロジェクトエクスプローラから「MyMacros」を右クリックし、[追加]→[モジュールの追加]をクリックしてモジュールを追加します。「Public Module ~」というセクションが既に記述済みなので、この中にマクロのルーチンを書きます。

 

マクロの実装

 まず、VSマクロでは「DTE(Development Tools Extensibility)」というIDE環境を拡張するためのグローバルなオブジェクトが用意されており、このオブジェクトをツリー上にたどっていくことで、開発環境に存在する膨大なオブジェクトを操作することができます。

 コードのポイントですが、まず、ソリューションエクスプローラで選択したファイルやフォルダの情報を取得するには、DTEオブジェクトのSelectedItemsプロパティを使います。

 あとは取得したものをFor Eachでループして、項目がProjectItemオブジェクトである場合、FileNames(1)で完全パスを参照できます。プロパティが配列型になっているのは、選択しているプロジェクトの項目によっては、関連付けられているファイルが複数になることもあるためです。ただ、ほとんどの場合は、1つのプロジェクト項目に対して1つのファイルです。

 ファイル名を取得できたら、あとはコマンド文字列を作成し、System.Diagnostics.Processを使ってプロセスを起動するだけです。

ファイル比較ツール起動マクロ
Sub Windiff_CompareFiles()
    '実行パスは個人の各環境に応じて書き換えてください。
    Dim diffPath As String = "C:\Program Files\Tools\Bin\WinDiff.Exe"
    Dim SelItem As SelectedItem
    Dim argStr As String

    '2つのアイテムが選択されていることの確認
    If (DTE.SelectedItems.Count <> 2) Then Exit Sub

    For Each SelItem In DTE.SelectedItems
        'プロジェクト内のアイテムなら処理する
        If (Not SelItem.ProjectItem Is Nothing) Then
            argStr = argStr + """" _
            + SelItem.ProjectItem.FileNames(1) + """ "
        End If
    Next

    Dim proc As System.Diagnostics.Process _
        = New System.Diagnostics.Process()
    proc.StartInfo.FileName = diffPath
    proc.StartInfo.Arguments = argStr
    proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal
    proc.Start()

End Sub

ツールバーへの登録

 マクロを作ったらツールバーへ登録しましょう。これで、2つのファイルを選択して、ツールバーからボタンをクリックすればWinDiffが比較を実行してくれます。

ツールバーから実行
ツールバーから実行
実行結果
実行結果

DF

 ところで、WinDiffもなかなかよいのですが、より高機能で使いやすい「DF」というすばらしいフリーソフトをここでは取り上げることにします。このツールもWinDiff同様、比較する際は2つのファイルパスを引数にとりますから、実行パスをこのDFをインストールした場所に書き換えれば、上記のマクロをそのまま使用することができます。

DFでの実行結果
DFでの実行結果

おわりに

 Visual Studioにはマクロ機能がついています。寡聞にしてVSのマクロをバリバリ活用しているという噂を余り聞かないのですが、意外と(?)使いものになります。あるものを使わないのももったいないので、アイデア次第でいろいろと活用して、CodeZineにもそのアイデアを投稿してください!

参考資料

  1. DTE オブジェクト
  2. ProjectItem オブジェクト
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • CodeZine編集部(コードジンヘンシュウブ)

    CodeZineは、株式会社翔泳社が運営するソフトウェア開発者向けのWebメディアです。「デベロッパーの成長と課題解決に貢献するメディア」をコンセプトに、現場で役立つ最新情報を日々お届けします。

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5