Jul 29, 2010

Windows 7のVirtualStoreに泣かされた

「C:\Program Files\foo\bar\hoge.txt」という位置にあるファイルを読み込んで処理するアプリケーションを開発していて、テストって事でhoge.txtを書き換えてみたのに、アプリケーションの方でhoge.txtを読み込んでみると、書き換える前の内容が返ってくるんですよ。え、このhoge.txtじゃなくて別の位置のhoge.txtを読みに行っちゃってるの? と思って「C:\Program Files\foo\bar\hoge.txt」を消してみると、「ファイルが見つかりません」ってエラーになるんですよね。だから見に行ってるのは確かにこのファイルで間違いないはずなのに。

僕は普段秀丸エディタを使ってるんですが、秀丸エディタって、書き込み権限が無いファイルを開くと「読み込み専用」って表示されて閲覧だけの状態になるんですよね。でも今回のhoge.txtはそうなってないから、ちゃんと書き換えも保存もできてるんですよ。一回秀丸エディタのウィンドウを閉じて、もう一度「C:\Program Files\foo\bar\hoge.txt」を開くと、さっき保存した時の内容になってるんで、書き込みに失敗したというわけでもない。なのに、自作のアプリで「C:\Program Files\foo\bar\hoge.txt」を開くと、秀丸エディタで書き換える前の内容が返ってくる。他にも同じ現象が起こってる人がいるみたいだし。何なんですかこれは?

……結論から言うと、犯人はWindows Vista以降で導入されたVirtualStoreという仕組みでした。

Windows Vista以降ではファイルに対して書き込みができない時に、「書き込めませんでした」というエラーを出す代わりに「C:\Users\ユーザ名\AppData\Local\VirtualStore」っていうフォルダの中にファイルを書き出すアプリケーションがあるみたいなんですね。今回は秀丸エディタがそうだったんですけど。実際、「C:\Users\ユーザ名\AppData\Local\VirtualStor\Program Files\foo\bar\hoge.txt」を見たら、さっき書き換えたはずの内容でhoge.txtが存在していました。

で、この状態で秀丸エディタで「C:\Program Files\foo\bar\hoge.txt」を開こうとすると、Windowsが「C:\Users\ユーザ名\AppData\Local\VirtualStor\Program Files\foo\bar\hoge.txt」の内容を返すみたいなんですよ。これはWindowsのファイル入出力の仕組みが透過的にやっていることらしくて、秀丸から見た時のファイルの位置はあくまで「C:\Program Files\foo\bar\hoge.txt」のままであるというのがポイント。で、この時メモ帳などの別のアプリケーションから「C:\Program Files\foo\bar\hoge.txt」を開くと、今度はVirtualStoreの方ではなく「C:\Program Files\foo\bar\hoge.txt」の実体の方が返される。その結果、「秀丸エディタとメモ帳でそれぞれ同じファイルを開いてるはずなのに、実際に見えてる内容が違う」という現象が起こる。

しかも最悪なことに、どうやら一回この状態に嵌ってしまうともうお手上げのようで、それ以後は秀丸ではVirtualStoreの方のファイルにしかアクセスできないんですよね。参った。もうVirtualStoreを全部消してしまいたい位なんですけど、VirtualStoreを見てみると他にもいろんなファイルが存在してるので、同じようにVirtualStoreの方の内容が返ってきてるお陰で正しく動作しているという状態のアプリケーションが他にもあるんだったら、不用意にVirtualStoreを消してしまうと大変なことになりかねないので消すわけにもいかない。

「コントロールパネル」→「管理ツール」→「ローカル セキュリティ ポリシー」で「セキュリティの設定」→「ローカル ポリシー」→「セキュリティ オプション」→「ユーザー アカウント制御:各ユーザの場所へのファイルまたはレジストリの書き込みエラーを仮想化する」を「無効」にするとVirtualStoreを無効にできるようなので、クリーンな環境でWindows VistaやWindows 7を使い始める時は、無効にしとくといいような気がします。本来できないはずの事をユーザに気取らせずにやろうとするから無理が生じるのであって、システムファイルをいじれるのは管理者権限がある人だけというルールを徹底していれば、無駄な混乱はしなくて済むのです。LinuxとかBSDとか、そういうものですし。

追記。付いたコメントの中に、僕の目には「Program Files以下にあるファイルをわざわざユーザが書き換えなきゃいけないという仕様が今の時代にはそもそもあり得ないでしょ。技術レベルの低い無能な似非プログラマがWindowsの仕様に逆ギレとか、まったく自業自得のくせに滑稽極まりないし。プププのプー」と言っているように見える物がいくつかあったけれども、Firefoxでいえばapplication.iniにあたるような、そう頻繁に書き換える訳じゃないけど可変のパラメータを外部ファイルで定義できるようにしておくためのファイルをいじってテストしてた時に遭遇した話なので、結構イラッとしました。


2019年4月25日追記。Windows 10になった今もVirtualStoreは仕組みとして存在し続けているのですが、さすがにこの時代になるとVirtualStoreのトラップに引っかかるアプリの方が時代後れでしょと言っていいような感じで、秀丸エディタも64bit版を使えばこの問題にハマらずに済むようになりました。よかったよかった。

エントリを編集します。

wikieditish message: Ready to edit this entry.











拡張機能