(for Internet Explorer)
Dim  MD5CacheClass::DefaultHashFileName as string
保存するときのデフォルトのファイル名。 Scan するときにデフォルトでスキップするファイル名。
Function  MD5CacheClass::GetHashFromStepPath( in_StepPath as string ) as string
ファイルの相対パスから、ファイル固有のハッシュ値を返します。
ソース
→ ToolsLib.vbs
ハッシュ値が登録されていなければ、Empty を返します。
または
の in_TargetPaths 引数に指定したフォルダーのパス(文字列)が、
相対パスの基準パスになります。 in_TargetPaths 引数に PathDictionaryClass のオブジェクトを指定
したときは、その BasePath プロパティが基準パスになります。
参考
Function  MD5CacheClass::GetFirstStepPathFromHash( in_HashValue as string ) as string
ファイル固有のハッシュ値から、存在する1つのファイルの相対パスを返します。
ソース
→ ToolsLib.vbs
参考
Sub  MD5CacheClass::SetHashValue( in_StepPath as string, in_HashValue as string )
ファイルのパスに、計算済みのファイル固有のハッシュ値を設定します。
ハッシュ値を計算するよりも早く処理します。
ソース
→ ToolsLib.vbs
in_HashValue 引数に Empty を指定すると、リストから除外されます。
すでに除外されているときは何もせず、エラーにもなりません。
【引数】
in_StepPath
in_HashValue
ファイルの相対パス。 基準は
(出力) in_StepPath に指定したファイルのハッシュ値
Sub  MD5CacheClass::Load( in_HashCachePath as string,
    in_TargetPaths as string or PathDictionaryClass )
計算済みのファイル固有のハッシュ値がたくさん記録されたファイルをロードします。
【引数】
in_HashCachePath
in_TargetPaths
ハッシュ値がたくさん記録されたファイルのパス
Empty、または、スキャンする対象のパス
in_TargetPaths に指定したフル パスを Me.TargetPaths に設定します。
in_TargetPaths に Empty を指定したら、in_HashCachePath の親フォルダーのパスを in_TargetPaths に
指定したときと同じ動きをします。 PathDictionaryClass のオブジェクトを指定することもできます。
ソース
→ ToolsLib.vbs
テスト
T_MD5Cache
→ T_fc.vbs
in_HashCachePath の基準パスは、カレント フォルダーです。
Sub  MD5CacheClass::Save( in_OutHashCachePath as string or Empty )
ファイル固有のハッシュ値をファイルに保存します。
【引数】
in_OutHashCachePath
ハッシュ値をたくさん記録するファイルのパス
などで登録されたハッシュ値とタイム スタンプを出力します。
2999-12-31T00:00:00Z af7da95e0ba5ff3c49b5c11d3645db85 t10.txt
2999-12-31T00:00:00Z 4787fe8ae24c12988db6b8dbaf686b20 t11.txt
2999-12-31T00:00:00Z a461d688d013e47c4010387e7922940d t12.txt
サンプル
保存されたファイルの内容の例
↑相対パス
    g_FileHashCache.RemoveAll
    Set cache = new MD5CacheClass
    cache.Scan  "Folder", Empty, False
    cache.Save  "_HashCache.txt"
サンプル
フォルダーに入っているファイルのハッシュ値を計算して保存します
ソース
→ ToolsLib.vbs
in_OutHashCachePath が Empty のときは、Me.DefaultHashFileName に保存します。
基準は Scan 時のパス
テスト
T_MD5Cache
→ T_fc.vbs
Sub  MD5CacheClass::Scan(
    in_TargetPaths as Empty or string or PathDictionaryClass,
    in_ScanFilterPaths as Empty or string or PathDictionaryClass,
    in_IsCompareTimeStamp as boolean )
フォルダーに入っているファイルのハッシュ値を計算して登録します。
【引数】
in_TargetPaths
スキャンする対象のパス
調べるフォルダーのフィルター
in_ScanFilterPaths
in_IsCompareTimeStamp
タイム スタンプが変更されたときだけ再計算するかどうか
存在しないファイルは、ハッシュのリストから除外されます。
in_TargetPaths が Empty のときは、Me.TargetPaths を使います。 Empty でなければ、
Me.TargetPaths を上書きします。
Me.TargetPaths と in_ScanFilterPaths の両方で指定されたファイルを、登録します。

in_ScanFilterPaths が Empty のときは、Me.TargetPaths だけを使います。
したフォルダーに対して
Fragment
Scan するときは、注意してください。
ソース
→ ToolsLib.vbs
テスト
T_MD5Cache
→ T_fc.vbs
Sub  MD5CacheClass::Fragment(
    in_ScanFilterPaths as Empty or string or PathDictionaryClass,
    ref_CopiedCache as MD5CacheClass,  in_IsCheckFileHash as boolean )
登録されているハッシュ値と同じファイルがあれば、1つを除いて削除します。
【引数】
in_ScanFilterPaths
調べるフォルダーのフィルター
ハッシュ値が登録されている別のキャッシュ
ref_CopiedCache
in_IsCheckFileHash
削除するときにハッシュ値を再計算してチェックするかどうか
Me と in_ScanFilterPaths の両方で指定されたファイルが、削除される候補です。
in_ScanFilterPaths が Empty のときは、Me だけを使います。
"Me.Defragment" で復帰できる限り、同じ内容のファイルを削除します。
"Me" に入っているパスが指すファイルと同じ内容(同じハッシュ値)の
ファイルが、"in_CopiedCache" に入っているパスが指すファイル
にあるとき、"Me" に入っているパスのファイルを削除します。
"Me" に同じ内容のファイルが複数あるときも、1つを除いてファイルを削除
します。
"ref_CopiedCache.DictionaryFromHash( hash )( 0 )" が指すパスにファイルが
存在するように "ref_CopiedCache.DictionaryFromHash( hash )" 配列の要素の
順番が入れ替わります。 削除する前のファイルのコピーが入ったフォルダーが
ゴミ箱に入ります。
削除されたファイルは、
で、復帰できます。
ソース
→ ToolsLib.vbs
テスト
T_MD5Cache_Fragment
→ T_fc.vbs
Sub  MD5CacheClass::Defragment(
    in_ScanFilterPaths as Empty or string or PathDictionaryClass,
    in_CopiedCache as MD5CacheClass )
ハッシュ値が登録されているファイルがなければ、同じハッシュ値のファイルからコピーします。
【引数】
in_ScanFilterPaths
調べるフォルダーのフィルター
ハッシュ値が登録されている別のキャッシュ
ref_CopiedCache
Me と in_ScanFilterPaths の両方で指定されたファイルが、コピーされる候補です。
in_ScanFilterPaths が Empty のときは、Me だけを使います。
Me の中のハッシュ値と同じハッシュ値を持つ ref_CopiedCache の中の
"in_CopiedCache.DictionaryFromHash( hash )( 0 )" が指すファイルを、
Me.TargetPaths の中にコピーすることによって、
で削除されたファイルを復帰します。
ソース
→ ToolsLib.vbs
テスト
T_MD5Cache_Fragment
→ T_fc.vbs
    Set cache = new MD5CacheClass
    cache.Load  "_work\Folders_1_PartHash.txt", "_work\defragmented"

    Set copied_cache = new MD5CacheClass
    copied_cache.Load  "_work\Folders_1_Hash.txt", "_work\copy"

    cache.Defragment  Empty, copied_cache
サンプル
コピー先のフォルダーを指定するときは、Me.TargetPaths をコピー先のフォルダーに設定して
の in_TargetPaths 引数にコピー先のフォルダーを指定してから
Defragment してください。
から Defragment するか、
だけ(Me の中で唯一)あるときは、in_MoveTargets に指定したリストの中にある同じハッシュ値のパス
に、ファイルを移動します。 in_MoveTargets に指定したリストの中にないファイルは、そのファイルと
Me の中のハッシュ値を削除します。もし、in_MoveTargets に指定したリストが不足していると、
Sub  MD5CacheClass::Delete( in_DeletingFolderPath as string,
    in_MoveTargets as array of MD5CacheClass )
フォルダーを削除します。
【引数】
in_DeletingFolderPath
削除するフォルダーのパス
参照しているフラグメントがある可能性があるハッシュの辞書の配列
in_MoveTargets
できなくなるので、注意してください。
で削除されたファイルと同じハッシュ値のファイルが、削除しようとしているフォルダーの中
Sub  MD5CacheClass::Verify(
    in_ScanFilterPaths as Empty or string or PathDictionaryClass )
存在するファイルのハッシュ値が正しいかどうかを再計算してチェックします。
【引数】
in_ScanFilterPaths
調べるフォルダーのフィルター
Me に登録されているファイルのうち、存在するファイルについて、ハッシュ値が正しいかどうかを
再計算して、Me に登録されているハッシュ値と等しいことをチェックします。
等しくないファイルがあったら、そこでエラーになります。
ソース
→ ToolsLib.vbs
テスト
T_MD5Cache_Fragment
→ T_fc.vbs
ファイルの存在についてチェックするときは、
Sub  MD5CacheClass::CheckFileExistsAnywhereInFileList( _
    in_HashFilePath  as string  or PathDictionaryClass of Nothing )
一覧ファイルに書かれたハッシュ値と、同じ内容のファイルが別に存在するかどうかをチェックします。
【引数】
in_HashFilePath
ハッシュ値が書かれた一覧ファイルのパス
ソース
→ ToolsLib.vbs
内部では、"Me.DictionaryFromHash( hash )( 0 )" が指すパスに、ファイルが存在するように
"Me.DictionaryFromHash( hash )" 配列の要素の順番が入れ替わります。
該当するハッシュ値を持つファイルの内容はチェックしません。 ファイルの内容をチェックするときは、
テスト
T_MD5Cache_Fragment
→ T_fc.vbs
in_HashFilePath が指すパス以外に、Me が指すパスにファイルがあれば、それをコピーして復活
(Defragment)できるので、その場合はエラーにはなりません。
Sub  MD5CacheClass::IsSameHashValuesOfLeafPathDictionary(
    arg_2ndLeafPathDictionary as string or LeafPathDictionary,
    in_2ndBasePath as MD5CacheClass )
フォルダーに入っているファイルのハッシュ値のセットが、Me に登録されているものと同じか比較します。
【引数】
arg_2ndLeafPathDictionary
調べるフォルダー、または、ファイルの集合
調べるフォルダーのパス
in_2ndBasePath
未確認
ソース
→ ToolsLib.vbs
で管理するファイルの属性。
.HashValue
MD5 ハッシュ値
.TimeStamp
string
Date
タイムスタンプ
PatchAndBackUpDictionaryClass は、ファイルを置き換えるパッチにおける、ファイルの一覧です。
.PatchRootPath
パッチ フォルダーのフル パス。 置き換えた後のファイルがある。
作成する予定のパッチに入れる、パッチ フォルダーのルートのパス。
.BackUpRootPath
.PatchPaths
.BackUpPaths
テスト
ソース
→ T_LeafPath.vbs
T_LeafPath
→ ToolsLib.vbs
バックアップ フォルダーのフル パス。 置き換える前のファイルがある。
作成する予定のパッチに入れる、バックアップ フォルダーのルートのパス。
パッチ フォルダーにあるファイルの一覧。
バックアップ フォルダーにあるファイルの一覧。
フォルダーから、ファイルの一覧を生成します
パッチをあてるように、ファイルの一覧を変更します
パッチに入れるファイルの一覧を作成します
back_up
patch
置き換えた後のファイルがある
置き換える前のファイルがある
メンバー
・patch フォルダー = SyncFilesX のワーク
・back_up フォルダー = SyncFilesX のベース
パッチ自体の更新内容の確認方法
で、古いパッチと、新しいパッチの違いを確認することができます。
パッチが行う更新内容の確認方法
を使って、patch フォルダーと back_up フォルダーの差分を確認することで、
パッチが行う更新内容を確認することができます。
ただし、SyncFilesX では、以下のように読み替えをしてください。
キーは、削除する前に比較するファイルのフル パス。 アイテムの Name
は、その実体となる存在するファイルのフル パス。
キーは、コピー元のフル パス。 アイテムの Name は、その実体となる
存在するファイルのフル パス。
・相対パスP = GetStepPath( patch.PatchPaths.Key,   patch.PatchRootPath )
・相対パスB = GetStepPath( patch.BackUpPaths.Key,  patch.BackUpRootPath )
・相対パスT = GetStepPath( full_path_T,            base_path_T )
ただし、
・patch は、PatchAndBackUpDictionaryClass のオブジェクト
・full_path_T は、パッチをあてる対象であるファイル T のフル パス
・base_path_T は、パッチをあてるときに指定する対象のベース フォルダーのパス
あるファイル T に対する置き換える前後のファイル(B,P) は、次の相対パスP, B, T がすべて
同じという関係があります。
.Copy()
コピーしたオブジェクトを生成します。
関数
パッチをあてます
参考
Sub  AttachPatchAndCheckBackUp( in_PatchTargetPath as string,  in_BackUpTargetPath as string,
    in_PatchPath as string,  in_BackUpPath as string )
【引数】
in_PatchTargetPath
in_PatchPath 引数が対象とするルートのフォルダーのパス
in_BackUpTargetPath
パッチをあてます。
in_BackUpPath 引数が対象とするルートのフォルダーのパス
削除または上書きされる前の内容が入った back_up フォルダーのパス
in_BackUpPath
コピー元ファイルが入った patch フォルダーのパス
in_PatchPath
内部で
を使っています。
ソース
→ ToolsLib.vbs
テスト
→ T_LeafPath.vbs
T_PatchAndBackUp_1
T_PatchAndBackUp_Moved
バックアップ ファイルが同じ内容かどうかを調べるのに、
を使っています。
ソース
→ ToolsLib.vbs
Function  EnumerateToPatchAndBackUpDictionary( in_Path as string ) as PatchAndBackUpDictionaryClass
【引数】
in_Path
フォルダーのパス
返り値
テスト
フォルダーから、PatchAndBackUpDictionaryClass のオブジェクトを生成します。
→ T_LeafPath.vbs
T_LeafPath
パッチ ファイルの一覧
T_PatchAndBackUp
in_Path 引数には、patch フォルダーと back_up フォルダーの両方が入っているフォルダーのパスを指定します。
返り値のキーとアイテムには、フル パスが格納されます。
    files = Empty
    g_FileHashCache.RemoveAll
    Set patch = EnumerateToPatchAndBackUpDictionary( "patch" )
    AttachPatchAndBackUpDictionary  files, "target", patch, False  '//(out)files
    CopyFilesToLeafPathDictionary  files, True
サンプル
"target" フォルダーに、パッチ( "patch\patch" & "patch\back_up" フォルダー )をあてます。
EnumerateToPatchAndBackUpDictionary
patch フォルダーと back_up フォルダーのパスをそれぞれ指定するとき
Function  MakePatchAndBackUpDictionary( _
    in_AttachedLeafPathDictionary as dictionary, in_RootPathInAttachedLeafPath as string, _
    in_BaseLeafPathDictionary as dictionary,     in_RootPathInBaseLeafPath as string, _
    in_PathOfPatchAndBackUp as string ) as PatchAndBackUpDictionaryClass
ファイルの一覧から、PatchAndBackUpDictionaryClass のオブジェクトを生成します。
【引数】
in_AttachedLeafPathDictionary
パッチをあてた後のファイルの一覧、または、Empty
in_RootPathInAttachedLeafPath
in_BaseLeafPathDictionary
in_RootPathInBaseLeafPath
パッチのルートにする、パッチをあてた後のフォルダーのパス
パッチをあてる前のファイルの一覧、または、Empty
パッチのルートにする、パッチをあてる前のフォルダーのパス
in_PathOfPatchAndBackUp
作成する予定の、パッチのルートのパス、または、Empty
パッチ自体(フォルダー)は作成しません。 作成するときは、本関数を呼び出した後で、
を呼び出してください。
ソース
→ ToolsLib.vbs
テスト
→ T_LeafPath.vbs
T_LeafPath_MakePatch
in_AttachedLeafPathDictionary 引数、または、in_BaseLeafPathDictionary 引数に、値が Empty の変数を
指定すると、その変数に
が格納されます。 そのキーとアイテムには、フル パスが
T_PatchAndBackUp
返り値
    Set patch = MakePatchAndBackUpDictionary( _
        Empty, "02", Empty, "01", _
        "_work\Patch" )
    CopyFilesToLeafPathDictionary  patch, False
        '// "_work\Patch" に、パッチのフォルダーができます。
サンプル
サンプル
    files = Empty
    g_FileHashCache.RemoveAll
    Set patch = MakePatchAndBackUpDictionary( _
        Empty, "patch", Empty, "back_up", Empty )
    AttachPatchAndBackUpDictionary  files, "target", patch, False
    CopyFilesToLeafPathDictionary  files, True
"01" フォルダーから "02" フォルダーができるパッチを "_work\Patch" フォルダーに作成します。
"target" フォルダーに、パッチ( "patch" & "back_up" フォルダー )をあてます。
MakePatchAndBackUpDictionary
MakePatchAndBackUpDictionary
格納されます。
Sub  ChangeKeyOfPatchAndBackUpDictionaryToTarget( _
    arg_PatchAndBackUpDictionary as PatchAndBackUpDictionaryClass, _
    in_TargetPath as string or array of string )
パッチのパス .BackUpRootPath, .PatchRootPath, .BackUpPaths, .PatchPaths をあてる対象に移動します。
【引数】
arg_PatchAndBackUpDictionary
in_TargetPath
パスを変更するパッチ
パッチをあてる対象のフォルダーのパス
in_TargetPath に指定したフォルダーのパスに、patch.BackUpRootPath と patch.PatchRootPath が変更され
ます。 ただし、patch は、arg_PatchAndBackUpDictionary 引数とします。 また、それに合わせて、
patch.BackUpPaths と patch.PatchPaths のキーを変更します。 patch.BackUpPaths と patch.PatchPaths の
アイテムの Name プロパティは、パッチとバックアップのファイルを指したままであり、本関数を呼び出した
後でもパッチをあてることができます。
サンプル
    Set  patch = new PatchAndBackUpDictionaryClass
    patch.PatchRootPath = "C:\A\patch"
    Set patch.PatchPaths = EnumerateToLeafPathDictionary( patch.PatchRootPath )
    patch.BackUpRootPath = "C:\A\back_up"
    Set patch.BackUpPaths = EnumerateToLeafPathDictionary( patch.BackUpRootPath )

    ChangeKeyOfPatchAndBackUpDictionaryToTarget  patch, "Target"

    AttachPatchAndBackUpDictionary  files, patch, "Target", False
    CopyFilesToLeafPathDictionary  patch, False
本関数は、複数のパッチをそれぞれ異なる対象フォルダーにあてることができるようにするために、主に
の内部から呼び出されます。
patch.BackUpRootPath
patch.PatchRootPath
"C:\A\back_up"
"C:\A\patch"
patch.BackUpPaths.Key(0)
"C:\A\back_up\1.txt"
"C:\A\patch\1.txt"
patch.PatchPaths.Key(0)
patch.BackUpPaths.Item(0).Name
"C:\A\back_up\1.txt"
patch.PatchPaths.Item(0).Name
"C:\A\patch\1.txt"
ChangeKeyOfPatchAndBackUpDictionaryToTarget
呼び出す前
呼び出した後
ChangeKeyOfPatchAndBackUpDictionaryToTarget を呼び出す前後の値の例:
"C:\A\patch\1.txt"
"C:\A\back_up\1.txt"
"C:\Target\1.txt"
"C:\Target\1.txt"
"C:\Target"
"C:\Target"
T_LeafPath の ChangePatchToTarget
ソース
→ ToolsLib.vbs
テスト
→ T_LeafPath.vbs
in_TargetPath に配列を指定すると、パッチとバックアップで、パッチをあてる対象のフォルダーが異なるとき
の処理ができます。 in_TargetPath( 0 ) にはパッチに対する対象のフォルダーのパスを、in_TargetPath( 1 )
にはバックアップに対する対象のフォルダーのパスを指定します。 関数から返ると、patch.PatchRootPath と
patch.BackUpRootPath は in_TargetPath( 0 ) と in_TargetPath( 1 ) の
サンプル
    Set  patch = new PatchAndBackUpDictionaryClass
    patch.PatchRootPath = "C:\A\patch"
    patch.PatchPaths = EnumerateToLeafPathDictionary( patch.PatchRootPath )
    patch.BackUpRootPath = "C:\AA\back_up"
    patch.BackUpPaths = EnumerateToLeafPathDictionary( patch.BackUpRootPath )

    ChangeKeyOfPatchAndBackUpDictionaryToTarget  patch,  Array( "Target\P", "Target\B" )

    target_path = patch.PatchRootPath
    AttachPatchAndBackUpDictionary  files, patch, target_path, False
    CopyFilesToLeafPathDictionary  patch, False
"C:\Target"
"C:\Target"
"C:\Target\B\1.txt"
"C:\Target\P\1.txt"
"C:\AA\back_up\1.txt"
"C:\A\patch\1.txt"
呼び出した後
呼び出す前
"C:\A\patch\1.txt"
patch.PatchPaths.Item(0).Name
"C:\AA\back_up\1.txt"
patch.BackUpPaths.Item(0).Name
patch.PatchPaths.Key(0)
"C:\A\patch\1.txt"
"C:\AA\back_up\1.txt"
patch.BackUpPaths.Key(0)
"C:\A\patch"
"C:\AA\back_up"
patch.PatchRootPath
patch.BackUpRootPath
ChangeKeyOfPatchAndBackUpDictionaryToTarget を呼び出す前後の値の例:
のフォルダーになります。 ただし、patch は、arg_PatchAndBackUpDictionary 引数とします。
パッチとバックアップで、パッチをあてる対象のフォルダーが同じとき
パッチとバックアップで、パッチをあてる対象のフォルダーが異なるとき
ChangeKeyOfPatchAndBackUpDictionaryToTarget
    files = Empty
    g_FileHashCache.RemoveAll
    Set patch_A = EnumerateToPatchAndBackUpDictionary( "PatchA" )
    Set patch_B = EnumerateToPatchAndBackUpDictionary( "PatchB" )
    Set patch = patch_A.Copy()

    MergePatchAndBackUpDictionary  patch, "Target\A", patch_B, "Target\B"

    target_path = patch.PatchRootPath
    AttachPatchAndBackUpDictionary  files, patch, target_path, True  '//(out)files
    CopyFilesToLeafPathDictionary  files, True
Sub  MergePatchAndBackUpDictionary( _
    arg_Destination as PatchAndBackUpDictionaryClass,  in_TargetRootPathOfDestination as string, _
    in_Source as PatchAndBackUpDictionaryClass,        in_TargetRootPathOfSource as string )
PatchAndBackUpDictionaryClass のパッチをマージします。
【引数】
arg_Destination
in_Source
(入力) マージする前A、(出力) マージした後
マージする前B
サンプル
MergePatchAndBackUpDictionary
ソース
→ ToolsLib.vbs
テスト
→ T_LeafPath.vbs
T_PatchAndBackUp_Merge
T_PatchAndBackUp_Merge_CheckToTest
patch_A と patch_B をマージした patch を作成し、パッチをあてます
arg_Destination の BackUp になくて Patch にファイルがあり、in_Source の BackUp にあって Patch にない場合は、
arg_Destination と in_Source の順にパッチをあてるとエラーになります(削除→追加と逆順なため)。
更に、arg_Destination の BackUp にあって Patch になく、in_Source の BackUp になくて Patch でもある場合は、
マージしなければ両方のパッチをアタッチできません。
arg_Destination と in_Source の両方に同じファイルに対するパッチがあり、内容が異なれば、どのようにしても、
エラーになります。
in_TargetRootPathOfDestination
in_TargetRootPathOfSource
Empty または、arg_Destination パッチをあてる対象フォルダーのパス
Empty または、in_Source パッチをあてる対象フォルダーのパス
in_TargetRootPathOfDestination と in_TargetRootPathOfSource の両方が Empty にできるのは、arg_Destination と
in_Source のパッチが同じフォルダーに対するパッチであるときだけです。 そのときは、マージした後の
arg_Destination.BackUpRootPath と arg_Destination.PatchRootPath は、パッチをあてる対象のフォルダーでは
なくなります。 片方だけ Empty にはできません。
内部で
を呼び出しています。 マージした後の
arg_Destination.BackUpRootPath と arg_Destination.PatchRootPath は、in_TargetRootPathOfDestination と
in_TargetRootPathOfSource に
のパスになります。
参考
in_TargetRootPathOfDestination と in_TargetRootPathOfSource に配列を指定することもできます。
参考
in_TargetRootPathOfDestination と in_TargetRootPathOfSource に配列を指定することもできます。
サンプル
    MergePatchAndBackUpDictionary  patch_A,  Array( "Target\P", "Target\B" ), _
        patch_B, ( "Target\P", "Target\B" )
MergePatchAndBackUpDictionary
    Set  patch = patch_A.Copy()
    ChangeKeyOfPatchAndBackUpDictionaryToTarget  patch,  Array( "Target\P", "Target\B" )
    MergePatchAndBackUpDictionary  patch,  patch.PatchRootPath,  patch_B, ( "Target\P", "Target\B" )
    MergePatchAndBackUpDictionary  patch,  patch.PatchRootPath,  patch_C, ( "Target\P", "Target\B" )
MergePatchAndBackUpDictionary
T_PatchAndBackUp_TwistedMerge