続・浦島太郎にならないために

とりあえずツリービューにディレクトリでも出してみた。
意味はない。
まぁこんなもんは慣れたもんでしょ…と思っていたらハマりました。
VistaUAC
噂には聞いてたけど、やっぱハマるんだ〜と妙に感動。

/// <summary>
/// <paramref name="node"/><paramref name="dir"/>で指定された情報を設定します。
/// <paramref name="dir"/>がサブディレクトリを持っていれば、<paramref name="level"/>で指定した階層分だけ再帰的に追加します。
/// </summary>
/// <param name="node">ディレクトリ情報を格納するTreeNode</param>
/// <param name="dir">起点となるディレクトリ</param>
/// <param name="level">サブディレクトリを処理する深さ。1はルートのみ。0で無制限。</param>
private void AddTreeNodes(ref TreeNode node, System.IO.DirectoryInfo dir, int level)
{
    node.Text = dir.Name;
    node.Tag = dir.FullName;

    if (--level != 0) {
        foreach (System.IO.DirectoryInfo childDir in dir.GetDirectories()) {
            TreeNode newNode = node.Nodes.Add(childDir.Name);
            AddTreeNodes(ref newNode, childDir, level);
        }
    }
}

上記のようなコードを書いたのだが、C:\Users\[USER_NAME]\Documents 以下を再帰処理するとSystem.UnauthorizedAccessExceptionが発生する。
ユーザディレクトリで怒られるとは思わなかった。

む〜…と画面を眺めていると、ツリービューに「My Music」が追加されている。
これってVistaで廃止されたんじゃ?

ちょいと調べてみると、廃止された訳ではなくて、
接合ポイント(ReparsePoint)として存在はしているようが、
アクセスしようとするとエラーになるとのこと。(by MSサポート)

んじゃ、DirectoryInfoに何か識別する情報持ってんだろjk。
インスペクトしてみると、Attributesプロパティが異なっているようだ。
My MusicのAttributesは、以下のようになっていた。

Hidden | System | Directory | ReparsePoint | NotContentIndexed

普通のディレクトリはDirectoryビットのみであったので、他をチェックしてやればよさそうだ。
……が、全部書くのはめんどくさい[接合ポイント]かつ[隠し]くらいでいいような気がしたので、とりあえずこんな感じに書き直した。

/// <summary>
/// <paramref name="node"/><paramref name="dir"/>で指定された情報を設定します。
/// <paramref name="dir"/>がサブディレクトリを持っていれば、<paramref name="level"/>で指定した階層分だけ再帰的に追加します。
/// </summary>
/// <param name="node">ディレクトリ情報を格納するTreeNode</param>
/// <param name="dir">起点となるディレクトリ</param>
/// <param name="level">サブディレクトリを処理する深さ。1はルートのみ。0で無制限。</param>
private void AddTreeNodes(ref TreeNode node, System.IO.DirectoryInfo dir, int level)
{
    node.Text = dir.Name;
    node.Tag = dir.FullName;

    if (--level != 0) {
        foreach (System.IO.DirectoryInfo childDir in dir.GetDirectories()) {
            if ((childDir.Attributes & 
                 (System.IO.FileAttributes.ReparsePoint | System.IO.FileAttributes.Hidden)) == 0) {
                TreeNode newNode = node.Nodes.Add(childDir.Name);
                AddTreeNodes(ref newNode, childDir, level);
            }
        }
    }
}

とりあえず良さそうだが、脱浦島の道は険しい……