--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace FDK
+{
+ public class フォルダ
+ {
+ public static string 絶対パスを相対パスに変換する( string 基点フォルダの絶対パス, string 変換したいフォルダの絶対パス )
+ {
+ // 引数チェック
+ if( false == Path.IsPathRooted( 基点フォルダの絶対パス ) )
+ throw new FDKException( $"指定された基点フォルダが絶対パスではありません。[{基点フォルダの絶対パス}]" );
+ if( false == Path.IsPathRooted( 変換したいフォルダの絶対パス ) )
+ throw new FDKException( $"指定された変換対象フォルダが絶対パスではありません。[{変換したいフォルダの絶対パス}]" );
+
+ if( '\\' != 基点フォルダの絶対パス[ 基点フォルダの絶対パス.Length - 1 ] )
+ 基点フォルダの絶対パス += @"\"; // 末尾は必ず \ にする
+
+ // 絶対-相対パス変換は、Path ではなく Uri でしか行えない。
+ var 基点uri = new Uri( 基点フォルダの絶対パス );
+ var 変換前uri = new Uri( 変換したいフォルダの絶対パス );
+ var 変換後uri = 基点uri.MakeRelativeUri( 変換前uri );
+
+ // Uri をデコードして返す。'/' は '\' に置換する。
+ return Uri.UnescapeDataString( 変換後uri.ToString() ).Replace( oldChar: '/', newChar: '\\' );
+ }
+
+ public static void フォルダ変数を追加する( string 変数名, string 置換するパス文字列 )
+ {
+ フォルダ.フォルダ変数toパス[ 変数名 ] = 置換するパス文字列;
+ }
+ public static void フォルダ変数を削除する( string 変数名 )
+ {
+ if( フォルダ.フォルダ変数toパス.ContainsKey( 変数名 ) )
+ フォルダ.フォルダ変数toパス.Remove( 変数名 );
+ else
+ throw new FDKException( $"指定されたフォルダ変数「{変数名}」は存在しません。" );
+ }
+ public static string 絶対パスに含まれるフォルダ変数を展開して返す( string path )
+ {
+ foreach( var kvp in フォルダ.フォルダ変数toパス )
+ {
+ if( kvp.Value.Nullまたは空である() )
+ continue;
+ path = path.Replace( "$(" + kvp.Key + ")", kvp.Value );
+ }
+
+ return path;
+ }
+ public static string 絶対パスをフォルダ変数付き絶対パスに変換して返す( string path )
+ {
+ foreach( var kvp in フォルダ.フォルダ変数toパス )
+ {
+ if( kvp.Value.Nullまたは空である() )
+ continue;
+ path = path.Replace( kvp.Value, "$(" + kvp.Key + ")" );
+ }
+
+ return path;
+ }
+
+ private static readonly Dictionary<string, string> フォルダ変数toパス = new Dictionary<string, string>();
+ }
+}