Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

あるパスから全てのジャンクションを解決したパス(要するに本来の場所のパス)を取得したいと思った。
汚いなりに形が出来たと喜んだのも束の間、対象としたい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してはダメ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away