.NET アセンブリ入門

Merge .NET アセンブリは、ユーザーに Merge GUI を提供する必要のないアプリケーションで、テキスト比較やレポーティング機能を利用できるようにします。たとえば、ウェブ サーバー アプリケーションは、テキストの比較または HTML 比較レポートを生成するために .NET アセンブリを使用するかもしれません。

.NET アセンブリは、C#、Visual Basic、F# などの .NET をサポートするあらゆるプログラミング言語から簡単に使用することができます。

機能と制限

.NET アセンブリは、2 つまたは 3 つのファイルあるいは文字列に基づいたテキスト比較を行う能力を提供します。比較結果はプログラムからアクセスすることができます。いくつかの種類のテキスト比較レポートも生成することができます。

フォルダー、イメージ、およびバイナリ比較はアセンブリでサポートされていません。どれも仮想ファイル システム(VFS)プラグインではありません。

以下のいずれかの操作を実行する必要がある場合は、前述の制約を考えると、オートメーション API またはコマンドライン ユーティリティがより適切です。

  • ユーザーに Merge ユーザー インターフェイスを提示する
  • .NET をサポートしないアプリケーションと Merge を融合する
  • .NET アセンブリではサポートされない Merge 機能を使用する

ライセンス

Araxis Merge ソフトウェア エンドユーザー ライセンス契約書には、デスクトップで使用する場合と、複数のユーザーにサービスを提供するサーバー アプリケーションのコンポーネントとして Merge を展開する場合のための、特定の条項があります。最終的条件については、完全な EULA(エンドユーザー ライセンス契約書)を参照されるでしょうが、要約すると、サーバー コンポーネントとして展開するには、通常のデスクトップ使用に必要な 1 つのライセンスではなく、2 つの Merge ライセンスの購入が必要となります。

Visual Studio での .NET アセンブリ入門

Information 以下の手順は、Windows デスクトップ用の Visual Studio Community 2022 を使用して作成されています。また、Visual Studio の他のエディションにも広く適用可能であるはずです。

プロジェクトに Merge .NET アセンブリへの参照を追加する

Merge .NET アセンブリを使用する前に、アセンブリへの参照を Visual Studio プロジェクトへ追加する必要があります。

Information 以下の手順は .NET 6 以降を対象とするプロジェクト用です。それ以前の .NET フレームワークで使用する古い Merge .NET アセンブリ(araxis.merge.foundation.net.dll)の使用は推奨しません。

  • Visual Studio の ソリューション エクスプローラー から、プロジェクトを右クリックして、追加プロジェクト参照… を選択します。
  • 参照… をクリックします。
  • Merge インストール フォルダー(通常、C:\Program Files\Araxis\Araxis Merge)から、araxis.merge.foundation.net6.dll という名前の Merge .NET アセンブリ DLL を選択します。
  • 追加 をクリックします。araxis.merge.foundation.net6.dll参照マネージャー ダイアログにリストされます。
  • DLL 左側のチェック ボックスがオンになっていることを確認して、OK をクリックします。
  • プロジェクトは Merge .NET アセンブリへの参照を持ちました。

Merge .NET アセンブリのドキュメントを表示する

  • プロジェクトに Merge .NET アセンブリ参照を追加して、Visual Studio の表示オブジェクト ブラウザー メニュー項目を選択します。
  • Merge .NET アセンブリのドキュメントを見ることができるオブジェクト ブラウザー パネルが表示されます。

.NET アセンブリを使用する

Merge .NET アセンブリ自体で提供されるリファレンス ドキュメント(上記参照)への補足として、下記の例は、C# プログラミング言語での使用の基礎的な説明を提供します。

コードへ .NET アセンブリをインポートする

プロジェクトが Merge .NET アセンブリの参照を持つと、通常の方法でコードへそれをインポートすることができます。

using Araxis.Merge.Foundation;

比較オプションを準備する

テキスト比較を行う前に、ComparisonOptions オブジェクトを作成する必要があります。これは、比較がどのように行われるかを決めるために調整することができる多くのプロパティを持っています。

次のコードでは、ComparisonOptions オブジェクトが作成され、いくつかのプロパティがデフォルトから変更されています。一部のプロパティ(たとえば CompareWhiteSpace)は、アセンブリの列挙のいずれかで定義されている値を期待することに留意してください。

var options = new ComparisonOptions();
options.CollapsedContext = 2;
options.CollapseUnchangedBlocks = true;
options.CompareLineEndings = true;
options.CompareWhiteSpace =
    WhiteSpaceOptions.TreatWhitespaceRunsAsSingleSpace;
options.ReformatXml = true;
options.ShowLineEndings = true;
options.ShowLineNumbers = false;

テキストを比較する

テキスト比較は TextComparison オブジェクトを使用して行われます。それは 2 つの静的な比較メソッドを提供します。1 つは比較されるファイルの完全修飾パスを含んでいる文字列を受け付けます。もう 1 つは比較される本文の内容を含んでいる文字列を受け付けます。どちらも、上述したように ComparisonOptions オブジェクトを必要とします。

テキスト ファイルを比較する

次のコードは、UTF-8 文字エンコードでエンコードされた 2 つのファイルを比較します。

TextComparisonResults results = TextComparison.CompareFiles(
    options,
    "C:\\MyFolder\\File1.txt",
    Encoding.UTF8,
    "C:\\MyFolder\\File2.txt",
    Encoding.UTF8);

文字列を比較する

この例は、3 つの文字列を比較する方法を示します。

TextComparisonResults results = TextComparison.CompareText(
    options, buffer1, buffer2, buffer3);

比較の進捗状況を監視する

Merge 2013.4287 の時点で、比較の進捗状況の監視は、ProgressChanged イベントに比較用のイベント ハンドラーを提供することによって可能となります。次のコードで見られるように、イベント ハンドラーは ComparisonOptions オブジェクトを使用して指定されます。イベント ハンドラーに渡された ProgressChangedEventArgs オブジェクトの PercentComplete プロパティは、比較された行のパーセンテージを示します。Operation プロパティは、デバッグ目的のためだけに提供される情報文字列です。

static void ProgressChangedEventHandler(
    object sender,
    ProgressChangedEventArgs e)
{
    System.Console.WriteLine(
        string.Format(
            "{0}%: {1}", e.PercentComplete, e.Operation));
}

var options = new ComparisonOptions();
options.ProgressChanged += ProgressChangedEventHandler;

比較結果へアクセスする

CompareFilesCompareText はどちらも新しい TextComparisonResults オブジェクトを返します。この結果オブジェクトは実行された比較についての広範囲な情報を提供します。

3 者間比較では、左と中央バッファー(FirstBufferPair)間および中央と右バッファー(SecondBufferPair)間において結果が提供されます。一貫性を保つために、2 者間比較の結果は、関係する第 2 のバッファーのペアが存在しないにもかかわらず、FirstBufferPair と見なされます。

概略情報

次の例は、3 者間比較用の概略比較情報を出力する方法を示します。

ComparisonOptions オブジェクトの ReformatXml プロパティが true に設定されている場合、XML の整形におけるあらゆるエラーが ReformattingErrors プロパティに格納されることに留意してください。

System.Console.WriteLine(
    string.Format(
        "整形エラー: {0}",
        results.ReformattingErrors.Length == 0 ?
            "なし" : results.ReformattingErrors));
System.Console.WriteLine(
    string.Format(
        "バッファー 1 と 2 の違い: {0}",
        results.FirstBufferPair.HasChanges));
System.Console.WriteLine(
    string.Format(
        "バッファー 2 と 3 の違い: {0}",
        results.SecondBufferPair.HasChanges));

関連付けを理解する

Association オブジェクトのコレクションは、比較された 1 対のバッファーにおける、2 つのバッファー間の変更の詳細です。

Association オブジェクトは、比較ペアの左バッファー内の行範囲と対応する右バッファ-内の行範囲を関連付けます。

また、Association オブジェクトは未変更、変更、挿入、および削除テキストの集合体の関連を示す State プロパティを持っています。未変更のテキストについては、左と右の行範囲は、同じ行数を含みます。変更されたテキストについては、左と右の行範囲は長さが異なる場合があります。削除されたテキストについては、右の行範囲の長さはゼロです。また、挿入されたテキストについては、左の行範囲の長さはゼロです。

次のコードは、2 者間テキスト比較(あるいは 3 者間比較の左と中央のバッファー)の左右のバッファーを関連付ける Association オブジェクトの反復処理方法を示します。

System.Console.WriteLine("バッファー 1 と 2 の間の変更点:");
foreach (var association in results.FirstBufferPair.Associations)
{
    System.Console.WriteLine(
        string.Format("Lines {0}-{1} -> lines {2}-{3} [{4}]",
        1 + association.LeftBegin,
        1 + association.LeftEnd,
        1 + association.RightBegin,
        1 + association.RightEnd,
        association.State));
}

次のコードは、左バッファーのすべての行を反復処理して、それら行の状態(未変更、変更、挿入、または削除)を出力します。

System.Console.WriteLine(
    "最初のバッファー ペアの左バッファー行の状態:");
for (
    int i = 0;
    i < results.FirstBufferPair.LeftLineStates.Length;
    i++)
{
    System.Console.WriteLine(
        "行 {0} は {1} です",
        i + 1,
        results.FirstBufferPair.LeftLineStates[i]);
}

比較されたテキストの行へアクセスする

TextComparisonResults オブジェクトは、比較されたバッファーの全テキストへのアクセスを提供します。

次の例は、バッファー中の番号が付けられた行にアクセスする方法を示します。この関数は 1 ベースの行番号をとるのに対して、Merge .NET アセンブリ自身は 0 ベースの行番号で動作することに注意してください。

private static void OutputLine(
    TextComparisonResults results,
    int line,
    int bufferNumber)
{
    System.Console.WriteLine(
        string.Format(
            "バッファー {1} の行 {1} のテキスト: {2}",
            line,
            bufferNumber + 1,
            results.Buffer(bufferNumber).Substring(
                results.Lines(bufferNumber)[line - 1]
                    .OffsetInBuffer,
                results.Lines(bufferNumber)[line - 1]
                    .LengthWithoutEndOfLineCharacters)));
}

行内の変更部分へアクセスする

Merge 2017.4929 以降、CompareWithinLines オプションが InlineChangeType.Detailed または InlineChangeType.Simple に設定されたテキスト比較では、行内の変更は、変更されたテキスト ブロックに対して判断されます。TextComparisonResults オブジェクトのメンバー FirstBufferPair および SecondBufferPair には、それぞれ 2 つのメンバー(LeftInlineChangesRightInlineChanges)が含まれています。これらは InlineChanges の配列で、比較されたファイルまたはテキスト バッファーの行ごとに 1 つの配列要素を持ちます。

Information 行内の変更は、変更の関連付けの適用範囲に入っている行のみが考慮されます。LeftInlineChanges または RightInlineChanges 配列内の行の要素は、その行が挿入、削除、または変更なしのブロックを表す関連付けに属している場合は null になります。

次の例は、3 者間テキスト比較の、行内の変更を出力する方法を示します。Associations コレクションの変更の関連付けを処理して、行内の変更の詳細を出力します。InlineChanges 型の詳細については、Merge .NET アセンブリのドキュメントを参照してください。

private static void OutputAllInlineChanges(TextComparisonResults results)
{
  System.Console.WriteLine("第 1 と第 2 ファイル/バッファー間の行内の変更");
  OutputInlineChanges(results.FirstBufferPair);
  System.Console.WriteLine("第 2 と第 3 ファイル/バッファー間の行内の変更");
  OutputInlineChanges(results.SecondBufferPair);
}

private static void OutputInlineChanges(BufferPair bufferPair)
{
  foreach (var association in bufferPair.Associations)
  {
    // 変更されている変更ブロックの行のみを処理
    if (association.State == ChangeState.Changed)
    {
      for (var line = association.LeftBegin; line != association.LeftEnd; ++line)
      {
        System.Console.WriteLine(string.Format("[Left line {0}] {1}", line + 1, bufferPair.LeftInlineChanges[line]));
      }
      for (var line = association.RightBegin; line != association.RightEnd; ++line)
      {
        System.Console.WriteLine(string.Format("[Right line {0}] {1}", line + 1, bufferPair.RightInlineChanges[line]));
      }
    }
  }
}

比較レポートを生成する

TextComparisonResults オブジェクトは、それらが表す比較結果のレポートを生成する機能を提供します。次のレポート タイプが使用可能です。HTML、XML、UNIX diff 編集スクリプト、UNIX diff コンテキストおよび UNIX diff ユニファイド。テキスト比較レポートの詳細については、ファイル比較レポートの作成を参照してください。

次のコードは、UTF-8 文字エンコードでエンコードされた HTML レポートを生成し、完全修飾パスが提供されているファイルにレポートを保存します。

results.Report(
    "C:\\MyFolder\\MyReport.html",
    Encoding.UTF8,
    ReportType.Html);

次の例は、UNIX diff ユニファイド レポートを生成します。レポート内に含まれるファイル パスは明示的に設定されます。ファイル パスは CompareFile メソッドを使用して生成された場合の結果オブジェクトには自動的に設定されますが、このケースのように CompareText が使用される場合には設定されないことに注意してください。

TextComparisonResults results = TextComparison.CompareText(
    options, buffer1, buffer2);
results.SetFilePath(0, "C:\\MyFolder\\File1.txt");
results.SetFilePath(1, "C:\\MyFolder\\File2.txt");
results.Report(
    "C:\\MyFolder\\MyUnifiedDiff.txt",
    Encoding.ASCII,
    ReportType.DiffUnified);

文字列の文字レベルの比較

文字列の文字レベルの比較は StringComparison オブジェクトを使用して可能です。

string str1 = "My first string ABC";
string str2 = "My second string A!C";
var options = new StringComparisonOptions();
var results = StringComparison.CompareStrings(options, str1, str2);
System.Console.WriteLine(results);

サポート

上記の説明や、Merge .NET アセンブリのリファレンス ドキュメントで答えが見つからない質問がある場合は、Araxis までお問い合わせください。