history | TOP |
2005/06/19:作成
overview | TOP |
Windows2000を使っていますが、時々掃除してやるとすっきりするフォルダがあります。たとえばWindows標準の一時フォルダとか。実際は、「コピーしたんなら後始末しとけよ」と自分が使うときには気にもしないくせに、人には厳しく突っ込んでしまうわけですが。
このページでは、そんな風な中身をズバッと消しても問題ないはずのフォルダのパスを取得する方法を試します。実際にそのフォルダの中身を消すかどうかは、また、消してもよいかどうかは知りません。将来自分で消したくなったときのために、パスの取得方法だけでも書き留めておこうと思うわけです。
特殊フォルダの取得 | TOP |
まず、そういったフォルダはほとんどが特殊フォルダとしてWindowsも特別扱いしています。ですので、それなりに取得する方法があります。現在は閉鎖されきってますが、「Delphi壁の穴」というサイトで紹介されていた関数を(自分なりに整形した記憶がないのでおそらくそのまま)紹介します。この関数を使うとほとんど今回のページで紹介しようとしているゴミフォルダを網羅してしまうんですが...
ちなみに、コメント内のURLはリンク切れです。
uses Windows, Forms, ShlObj; //----------------------------------------------------------------------------- // 特殊フォルダ // http://hp.vector.co.jp/authors/VA009712/take/delphi/kabesys.htm#ishelllink function GetSpecialFolderPath(const Folder: integer): string; var pidlPath: PItemIDList; SpecialPath: array[0..MAX_PATH] of Char; begin SHGetSpecialFolderLocation(Application.Handle, Folder, pidlPath); SHGetPathFromIDList(pidlPath, Special); Result := Special; end;
最近使ったファイル | TOP |
まず手始めに、「最近使ったファイル」です。2回目ですがWindows2000です。NTやXPでどうなるかは興味ありません。で、Windows2000ではユーザー別にそういうフォルダを管理しているので、Administratorで普段使っている今の環境では「C:¥Documents and Settings¥Administrator¥Recent」が戻ります。
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(GetSpecialFolderPath(CSIDL_RECENT)); end;
インターネットキャッシュ | TOP |
次に「インターネットキャッシュ」フォルダです。通常は、なんかえらく深いところにありますが、気持悪いのでデスクトップのIEアイコンのプロパティで変更しています。当然ですが、ここではその変更後のフォルダパスを取得できます。
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(GetSpecialFolderPath(CSIDL_INTERNET_CACHE)); end;
クッキー | TOP |
次にクッキーです。またもやインターネット関係ですが、定義済みですので仕方がありません。前述の関数を使って取得できるゴミフォルダを列挙しているだけですので。
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(GetSpecialFolderPath(CSIDL_COOKIES)); end;
履歴 | TOP |
またもやですが、次は履歴フォルダです。なんか、クッキーとか履歴とかキャッシュとか置き場所がバラバラで気持が悪いです。
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(GetSpecialFolderPath(CSIDL_HISTORY)); end;
ユーザー環境変数の取得 | TOP |
さて、先ほどの便利関数のことは忘れて、次に進みます。今度は一時フォルダの取得に進みます。ところで、TEMPフォルダには(多分)2種類あって、一つはシステム全体のもの、もう一つはAdministratorなどのログオンユーザー用のものです。ここでは、ログオンユーザー用のものを取得します。
その前に、GetEnvironmentVariableという関数があることを確認しておきます。
//----------------------------------------------------------------------------- // 環境変数の取得 // http://dmj.psnet.ne.jp/mn/?NO=53 function GetEnvironmentVariable(const s: string): string; const BUF_SIZE = 8192; begin SetLength(Result, BUF_SIZE); SetLength(Result, Windows.GetEnvironmentVariable(PChar(s), PChar(Result), BUF_SIZE)) end;
これは、デスクトップのマイコンピュータのプロパティで確認できる環境変数を取得するための関数です。ただし、TEMPフォルダのようにログオンユーザーとシステム全体の両方でかぶっている環境変数名がある場合は、どうもログオンユーザーの値が優先されるような気がします。以降では、「ログオンユーザー用の」という意味で「ユーザー...」という言葉を使います。
ユーザー一時フォルダ | TOP |
そのままです。ただし、パスが深すぎるのか省略した形でパスが戻されます。どこかに長いパスに変換する方法があったような気がします。また、「TEMP」も「TMP」も戻ってくる答えが同じ、つまり同じパスを指しているようなんですが念のため。
procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(GetEnvironmentVariable('TEMP')); ShowMessage(GetEnvironmentVariable('TMP')); end;
システム一時フォルダ | TOP |
システム全体での一時フォルダ(たいていは「C:¥WINNT¥Temp」だと思います)のパスを取得します。今度は少しややこしくなります。というのは前述の環境変数取得関数を使うと、ユーザー一時フォルダが戻ってきてしまうからです。これはシステム環境変数でも同じように「TEMP」「TMP」という名称が使用されているからだと思いますが、そのために(多分)レジストリを読まなければならない羽目に。
ただ、レジストリを直接読むと、たとえば「TEMP」フォルダが「%SystemRoot%¥Temp」なんて感じで得られてしまいます。じゃぁ「%SystemRoot%」ってなんどい、という問題が出てきてそれを求めて...というのをやってる関数です。
uses Registry; //----------------------------------------------------------------------------- // システム一時フォルダ取得 procedure GetSystemTempPath(var Temp, Tmp: string); const SYS_ENV = '\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; var Reg: TRegistry; SysRoot, WinDir: string; begin WinDir := ''; Temp := ''; Tmp := ''; // システム環境設定を直接読み取る(実際のパスではない) Reg := nil; try try Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKey(SYS_ENV, False) then begin // システムディレクトリ(%SystemRoot%) WinDir := Reg.ReadString('windir'); // システムTEMPパス(%SystemRoot%...) Temp := Reg.ReadString('Temp'); // システムTMPパス(%SystemRoot%...) Tmp := Reg.ReadString('Tmp'); Reg.CloseKey; end; finally FreeAndNil(Reg); end; except ; end; // 実際のシステムルートを取得して SysRoot := GetEnvironmentVariable('windir'); // パスを正しく置き換える Temp := StringReplace(Temp, WinDir, SysRoot, [rfIgnoreCase]); Tmp := StringReplace(Tmp, WinDir, SysRoot, [rfIgnoreCase]); end; procedure TForm1.Button1Click(Sender: TObject); var Temp, Tmp: string; begin GetSystemTempPath(Temp, Tmp); ShowMessage(Temp + #13#10 + Tmp); end;
ワトソン博士の使うフォルダ | TOP |
最後が、ワトソン博士の使うフォルダです。調子の悪いプログラムを使っていて何かのひょうしにワトソン博士が出現することがあります。このとき、素人には全くもって役に立たないログファイルとかダンプファイルを出力してくれます。根本的に個人ユースでは、そんなプログラムは使わないでいよう、とかOS入れなおそうかなんてことが比較的容易なため、ワトソン博士に教えてもらうことはありません、と信じています。ですので、ここではゴミフォルダの一つに認定しています。
ワトソン博士の使っているフォルダってどこよ? を調べてみるためにはワトソン博士の設定画面を見る必要があります。でもアクセサリにもいないようですので、「C:¥WINNT¥system32¥DRWTSN32.EXE」から直接起動してみることにします。
書いてありました。それにヘルプを確認してみると、既定値以外に設定した場合の記録場所(レジストリのパス)についても説明がありました。でもヘルプの既定値と実際の既定値が異なっているような気がしますが...
それからログについてはフォルダですが、ダンプについてはファイル名まで指定のような気がします。最近ダンプファイル吐かれてないし、設定したところでダンプファイルを任意のタイミングで吐くこともできないので未確認ですが。
//----------------------------------------------------------------------------- // ワトソン博士の使用するフォルダ取得 procedure GetWatsonPath(var Log, Dmp: string); const DR_ENV = '\SOFTWARE\Microsoft\DrWatson'; LOG_DEF = '\Documents and Settings\All Users\Documents\DrWatson'; DMP_DEF = '\Documents and Settings\All Users\Documents\DrWatson\user.dmp'; var Reg: TRegistry; SysDrive: string; begin Log := ''; Dmp := ''; // ワトソン博士の設定を読み取る Reg := nil; try try Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKey(DR_ENV, False) then begin Log := Reg.ReadString('LogFilePath'); Dmp := Reg.ReadString('CrashDumpFile'); Reg.CloseKey; end; finally FreeAndNil(Reg); end; except ; end; // システムドライブ取得 SysDrive := ExtractFileDrive(GetEnvironmentVariable('WINDIR')); // 既定値使用なら既定値で if Log = '' then Log := SysDrive + LOG_DEF; if Dmp = '' then Dmp := SysDrive + DMP_DEF; end; procedure TForm1.Button1Click(Sender: TObject); var Log, Dmp: string; begin GetWatsonPath(Log, Dmp); ShowMessage(Log + #13#10 + Dmp); end;
ゴミ箱を空にする | TOP |
本当の最後が、ゴミ箱を空にする方法です。多分どこかに乗ってるんだと思いますが、ここでは「Delphi4 TECH200 Rev.2」に載っていた方法をとります。っていうか写します。
なんか、shell32.dllには存在しているAPIなのに、少なくともDelphi6までは宣言されていないようです。ですので、これを、implementationの上に書いておきます。
//----------------------------------------------------------------------------- // ゴミ箱を空にする const SHERB_NOCONFIRMATION = $00000001; SHERB_NOPROGRESSUI = $00000002; SHERB_NOSOUND = $00000004; function SHEmptyRecycleBin(Wnd: HWND; pszRootPath: PChar; dwFlags: DWORD): integer; stdcall; external 'shell32.dll' name 'SHEmptyRecycleBinA';
で、使います。ここでは、3つ目の引数に0を渡しているので「確認画面を表示して、プログレス画面を表示して、音を出す」ということになります。
//----------------------------------------------------------------------------- // ゴミ箱を空にする procedure TMainForm.Button1Click(Sender: TObject); begin SHEmptyRecycleBin(Handle, '', 0); end;
あとがき | TOP |
そんなこんなで、以上をゴミフォルダと決めました。実際にはいつも使っているアプリケーションのログフォルダとかいろいろあるんでしょうが、Windows2000純正ということでこれだけとしておきます。こういうのを削除するプログラムを作ろうとして一撃必殺飽きてしまって忘れないうちにメモっておこうと思っただけです。
EOF | TOP |