| 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 |