Windowsにおける絶対パスと相対パスの判定や相互変換
のサンプルモジュールです。
#module ;必要なDLLをロードし、APIをインポート #uselib "kernel32" #func GetFullPathNameA "GetFullPathNameA" sptr, int, var, var #uselib "shlwapi" #cfunc PathIsRelativeA "PathIsRelativeA" sptr #func PathRelativePathToA "PathRelativePathToA" var, sptr, int, sptr, int ;必要なフラグ整数値 #const FILE_ATTRIBUTE_DIRECTORY 0x00000010 #const _MAX_PATH 260 ;ファイルパスが相対パスかどうか判定 #defcfunc is_relpath str _fpath return PathIsRelativeA(_fpath) ;ファイルパスが絶対パスかどうか判定 #defcfunc is_abspath str _fpath return (PathIsRelativeA(_fpath) == 0) ;相対パスを絶対パスに変換 ;to_abspath buffer, relpath[, curdir] ; ;引数 ; buffer 相対パスを格納するバッファ。 ; abspath 変換する絶対パス。 ; curdir 変換後の相対パスの基準となるカレントディレクトリのパス。省略時は ; dir_curの値が用いられる。 ; ;戻り値 ; 0 成功 ; -1 変換に失敗 (GetFullPathNameA関数が失敗) ; #define global to_abspath(%1,%2,%3="") _to_abspath %1,%2,%3 #deffunc _to_abspath var _buf, str _relpath, str _curdir ;カレントディレクトリを変更 if( _curdir != "" ){ is_chdir = 1 old_curdir = dir_cur chdir _curdir }else{ is_chdir = 0 } ;絶対パスに変換 sdim _buf, _MAX_PATH offset = 0 GetFullPathNameA _relpath, _MAX_PATH, _buf, offset if( stat == 0 ){ return -1 }else:if( _buf == "" ){ ;足りない文字数分のバッファを再確保して、再変換 bufsize = stat sdim _buf, bufsize offset = 0 GetFullPathNameA _relpath, bufsize, _buf, offset if( stat == 0 ): return -1 } ;カレントディレクトリを元に戻す if( is_chdir ): chdir old_curdir return 0 ;絶対パスを相対パスに変換 ;to_relpath buffer, abspath[, curdir] ; ;引数 ; buffer 相対パスを格納するバッファ。 ; abspath 変換する絶対パス。 ; curdir 変換後の相対パスの基準となるカレントディレクトリのパス。省略時は ; dir_curの値が用いられる。 ; ;戻り値 ; 0 成功 ; -1 指定されたパスが相対パスだった ; -2 カレントディレクトリと指定された絶対パスのドライブ文字が異なる (変換不可) ; -3 変換に失敗 (PathRelativePathTo関数が失敗) ; #define global to_relpath(%1,%2,%3="") _to_relpath %1,%2,%3 #deffunc _to_relpath var _buf, str _abspath, str _curdir ;カレントディレクトリが省略された場合は、現在のカレントディレクトリを使用する。 if( _curdir != "" ){ curdir = _curdir }else{ curdir = dir_cur } ;指定されたパスが絶対パスか判定 if( PathIsRelativeA(_abspath) ): return -1 ;ドライブが同じか判定 abspath = _abspath if( peek(curdir, 0) != peek(abspath, 0) ): return -2 ;相対パスに変換 sdim _buf, _MAX_PATH PathRelativePathToA _buf, dir_cur, FILE_ATTRIBUTE_DIRECTORY, _abspath, 0 if( stat == 0 ): return -2 return 0 #global
モジュールのテストコード。
;ファイルパス curdir = dir_cur abspath = "C:\\Windows\\explorer.exe" mes "カレントディレクトリ '"+curdir+"'" mes "" ;相対パスかどうか判定 if( is_relpath(abspath) ){ mes "'"+abspath+"'は相対パスです。" }else{ mes "'"+abspath+"'は相対パスではありません。" } ;絶対パスかどうか判定 if( is_abspath(abspath) ){ mes "'"+abspath+"'は絶対パスです。" }else{ mes "'"+abspath+"'は絶対パスではありません。" } ;相対パスに変換 to_relpath relpath, abspath, curdir if( stat ){ mes "相対パスへの変換に失敗しました。[ERROR "+stat+"]" stop } mes "" mes "'"+abspath+"'の相対パスは" mes "'"+relpath+"'です。" ;絶対パスに変換 sdim abspath, 0 to_abspath abspath, relpath, curdir if( stat ){ mes "絶対パスへの変換に失敗しました。[ERROR "+stat+"]" stop } mes "" mes "'"+relpath+"'の絶対パスは" mes "'"+abspath+"'です。"
参考サイト等。
- PathIsRelative パスが相対パスかどうかを判定 - MASAPICO'S Page
- PathRelativePathTo 二つのパス間の相対パスを取得 - MASAPICO'S Page
- ファイル属性フラグ値(VC++のヘッダ見れば分るのですが検索で済ませました) - Delphi Q&A 掲示板 過去ログ一覧
- フルパスから相対パスを取得 - Cyan's HSP
- GetFullPathName - MSDNライブラリ
- shlwapi に含まれる便利な API - Donut RAPT
- 標準関数とWIN32APIの対応表 - アークピット
- 相対パスから絶対パスを取得する、絶対パスから相対パスを取得する(.NET Framework) - DOBON.NET