読者です 読者をやめる 読者になる 読者になる

Windows Vistaでのユーザープロファイルの別ドライブへの移動(確定版)

おいらの趣味として、システムのディスク領域とデータのディスク領域を物理的に違うものにするってのがあるけど、Windowsの場合、ユーザー用の領域はシステムと同じCドライブに作られる。ある程度は変更できるけど、どうしても、Cドライブにデータが残る。 それでは気持ち悪くて、いろいろ試行錯誤した結果、多分、これで問題ないかな? シンボリックリンクの張り方を変えれば、XPでも2000でもOKだと思う。

  1. コンピュータ−管理−ローカルユーザーとグループを開いて、Administratorを有効にする。
  2. Administratorでログオン
  3. コンピュータ−プロパティ−システムの詳細設定−ユーザープロファイルを開く。
  4. ユーザープロファイルの移動先を”コピー先”で指定。
  5. レジストリのHKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\(ユーザーSID)\ProfileImagePathを編集。
  6. PCを再起動する。
  7. コマンドプロンプトを開いて、ユーザープロファイルが移動したか確認する。(デフォルトがユーザープロファイルの移動先になっているはず)
  8. コンピュータ−管理−ローカルユーザーとグループを開いて、Administratorを無効にする。
  9. 元のユーザープロファイルを削除する
  10. コマンドプロンプトを開いて、"mklink /d 移動元ユーザープロファイルフォルダ 移動先ユーザープロファイルフォルダ"を実行して、元のフォルダにシンボリックリンクを張る。

最後のプロセスで元フォルダにシンボリックリンクを張る必要があるのは、 APIを使わずにレジストリ読みか決め打ちか何かでユーザープロファイルフォルダにアクセスしている不作法なアプリのせい。 少なくとも、Google Desktopインストーラーは不作法なアプリだった。('A`)

てかさ、普通、ユーザープロファイルとかの取得って、SHGetSpecialFolderPathを呼び出すのが正式な作法な気がするけど、どうなんだろ。

char szPath[_MAX_PATH];
BOOL ret;

ret = ::SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, TRUE);
printf("CSIDL_APPDATA = %s ret = %d\n", szPath, ret);

ret = ::SHGetSpecialFolderPath(NULL, szPath, CSIDL_PERSONAL, TRUE);
printf("CSIDL_PERSONAL = %s ret = %d\n", szPath, ret);

確か、SHGetSpecialFolderPathはIE5がインストールされている必要があるから、あえて使わないのは、その辺の兼ね合いかもしれないけど。
それに、iniファイルとかの設定ファイルの類をアプリケーションと同じフォルダに突っ込んでいるケースがあるから、この辺も注意。
うかつに、"C:\Program Files\"の下に突っ込んで、UACが発動して設定ファイルがオープンできなく、アプリが実行できなくなる場合もあるし。
レジストリとかもそうだけど、ドメイン名を持っていたら、設定ファイルの保存先を"アプリケーション データ フォルダ\ドメイン名\アプリケーション名"って感じで区切れば、ほかのアプリと重複することはなさそう。
てか、そんな不作法なアプリを修正するのに、結構かかった。orz

2009/07/23 追記:
ユーザープロファイルを移動するとIEの履歴が表示されなくなるので、Administratorのユーザープロファイルから履歴をコピーする。
コピー方法は、ここ

2011/02/02 追記:
Windows Vista/7でユーザープロファイルを移動すると、バーチャルストアが効かなくなる模様。実際、RadPHPに関するトラブルを経験。