Desktop と DesktopDirectory

System.Environment.SpecialFolder 列挙体には Desktop と DesktopDirectory と言う 2 つの値が定義されています.

メンバ名 説明
Desktop 物理的なファイル システム上の場所ではない論理的なデスクトップ。
DesktopDirectory デスクトップ上のファイル オブジェクトを物理的に格納するために使用されるディレクトリ。
仮想フォルダであるデスクトップ フォルダ自体とこのディレクトリ フォルダを混同しないようにしてください。

http://msdn.microsoft.com/ja-jp/library/system.environment.specialfolder(v=VS.100).aspx

Desktop は論理的なデスクトップで,DesktopDirectory はデスクトップ上のファイル オブジェクトを物理的に格納するために使用されるディレクトを表すそうです.概念としては何となく分かるのですが,具体的に(特に,論理的なデスクトップが)どこを指すのか分からなかったので,以下のようなプログラムでそれぞれの値を確認しつつ実際に弄って調べてみました.

using System;
using System.Windows.Forms;

class Program {
    static void Main(string[] args) {
        MessageBox.Show("Desktop: " + Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
        MessageBox.Show("DesktopDirectory: " + Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));
    }
}

初期状態

特に何も設定を変更しない場合は,以下のように Desktop と DesktopDirectory (を指定した GetFolderPath() メソッド) は同じ結果を返します.

Desktop: C:\Document and Settings\clown\デスクトップ
DesktopDirectory: C:\Document and Settings\clown\デスクトップ

デスクトップフォルダをリネーム

次に,デスクトップフォルダをリネームしてみます.リネーム方法は@IT:Windows TIPS -- Tips:「デスクトップ」や「お気に入り」をネットワーク・フォルダに配置する などを見ると,レジストリ中の HKEY_CURRENT_USERのSoftware\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders の Desktop の値を変更しろと記述されていますが,単純にフォルダを「名前の変更」でリネームして再ログインする方法でも問題ないようでした(レジストリを変更しても元の値に戻されたような・・・).

この方法で,「デスクトップ」を「Desktop」にリネームした後の結果が以下になります.

Desktop: 
DesktopDirectory: C:\Document and Settings\clown\Desktop

DesktopDirectory の方はリネーム後のパスに追随しているのですが,Desktop の方は空文字が返ってくるようになってしまいました.

ジャンクションを作成

Windows では,「ジャンクション」と呼ばれるものを作成する事ができるそうです(参考:ジャンクション作成方法 - GeekなNooblog).この方法を用いてジャンクションを作成し,返ってくる値がどう変化するかを観察してみました.

junction.exe "C:\Documents and Settings\clown\デスクトップ" "C:\Documents and Settings\clown\Desktop"

まず,上記のようにして「デスクトップ」と言う名前でジャンクションを作成した結果が以下になります.この場合は,Desktop のパスが復活しました.

Desktop: C:\Document and Settings\clown\デスクトップ
DesktopDirectory: C:\Document and Settings\clown\Desktop

次に,「デスクトップ」のジャンクションを削除し,別の名前でジャンクションを作成してみました.

junction.exe "C:\Documents and Settings\clown\Desktop2" "C:\Documents and Settings\clown\Desktop"

この結果が下記になります.再び空文字が返るようになってしまいました.

Desktop:
DesktopDirectory: C:\Document and Settings\clown\Desktop

現状での結論

結局のところ,この 2 つの値(を指定して GetFolderPath() を実行した結果)は以下のような振る舞いをするようです.

  • DesktopDirectory は,現在の環境のデスクトップフォルダのパスを返す
  • Desktop は,%USERPROFILE%\デスクトップ と言う値を返す.ただし,この値に相当するパス(, ジャンクション, etc?)が存在しない場合は空文字を返す.

Desktop を指定した時に返る値もどこかを設定すれば変更できそうな気はするのですが,今のところよく分かってません.デスクトップフォルダのパスを取得すると言うサンプルコードを探すと,結構な頻度で Desktop の方を指定したものが引っかかりますが,上記のような挙動を考えると DesktopDirectory を指定する方が良さそうです.