LoginSignup
3
3

More than 5 years have passed since last update.

全てのジャンクションを解決したパスを取得したい

Last updated at Posted at 2016-11-06

あるパスから全てのジャンクションを解決したパス(要するに本来の場所のパス)を取得したいと思った。
汚いなりに形が出来たと喜んだのも束の間、対象としたいWindows7(PowerShell v2.0)では動かなそうなことが判明。

とりあえず現状を備忘録として残す。

思考の流れ

  1. Get-Item 'フォルダパス'System.IO.DirectoryInfoを取得すれば、Attributeからリパースポイント(ジャンクションなど)かどうかわかる(参考)。

  2. 一階層ずつジャンクションかどうか判断し、ジャンクションなら本来の場所へ移動して、また登って行けば良い。

  3. ルートフォルダまで辿り着いたら探索終了とし、それまで通ってきたフォルダの履歴をパスとして接合する。

出来上がったもの

Solve-JunctionPath.ps1
#引数の設定
Param(
    [Parameter (Mandatory=$true)]
    [String]$FilePath #=$Args[0]
)

[IO.FileSystemInfo]$argPath=Get-Item $FilePath

#一階層毎のフォルダ名配列 Leaf To Root
[Collections.Generic.IList[String]]$DirNameList = New-Object -TypeName Collections.Generic.List[String]


if ($argPath.Attributes -like "*Directory*")
{
    [IO.DirectoryInfo]$tmpDir = $argPath
} else {
    [IO.DirectoryInfo]$tmpDir = $argPath.Directory
}

do
{
    if ($tmpDir.Attributes -like "*ReparsePoint*")
    {
        $tmpDir = Get-Item $tmpDir.Target
    }

    #ジャンクション解決後のフォルダ名を取得する
    $DirNameList.Add($tmpDir.Name)

    $tmpDir = $tmpDir.Parent
}
until($tmpDir.FullName -eq $tmpDir.Root.FullName)

#Root To Leaf
$DirNameList.Reverse()


[String]$out = $tmpDir.FullName + ($DirNameList -join '\')

#フォルダを開く
Explorer.exe $out
#結果確認用
#$out

使用例

上記のコードを"Solve-JunctionPath.ps1"という名前で保存し、同じ場所に以下のようなbatファイルを作成する。

@PowerShell.exe -ExecutionPolicy RemoteSigned %~dp0\Solve-JunctionPath.ps1 '%~1'

このバッチファイルに調べたいパスを送ると、本来の場所のフォルダが開く。

問題の箇所

    if ($tmpDir.Attributes -like "*ReparsePoint*")
    {
        $tmpDir=Get-Item $tmpDir.Target
    }

PowerShell 2.0では
(161110修正)
DirectoryInfoのAttributesに再解析ポイントかどうかの情報を持たないので、
リンク先本来の場所の情報を持たない(.Targetプロパティが存在しない)ため、
この方法では辿ることができない。

実際、Get-Memberをしてみると.TargetプロパティはCodePropertyとなっている。
つまりPowerShell側で追加されたプロパティであるため、PowerShellのバージョンが低いと存在しないということになる。

対応策

とりあえず思いつく解決策としては、
cmd.exe /c dir "ディレクトリパス" /AL
の出力結果を正規表現なりで解析する方法。

更新日時 <JUNCTION> ジャンクション名 [参照先]
の形式で取得できるのでジャンクション名で判定し、参照先へ移動、すれば何とかなると思われる。

参考

PowerShell で シンボリックリンクを 使えるようにしよう
PowerShellでジャンクションを作ったら削除はRomove-Itemしてはダメ

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3