在共用電腦的環境下,使用者往往不希望他人發現自己的操作痕跡——瀏覽過的網址、輸入過的表單資料、執行過的指令等。雖然 Windows 提供手動清除功能,但項目分散、步驟繁瑣,極不方便。本文整理並整合多方資料,提供一個較為全面的 VC++ 實作方案,可一次性清除 17 類常見歷史記錄,並附完整原始碼供下載參考。
在 stdafx.h 中加入:
#include <atlbase.h>
專案屬性 → Link → 輸入 → 附加相依性,加入:
Wininet.lib shlwapi.lib
#include <wininet.h>
#include <UrlHist.h>
#define SWEEP_BUFFER_SIZE 10000
public:
enum DEL_CACHE_TYPE { File, Cookie };
BOOL DeleteUrlCache(DEL_CACHE_TYPE type);
BOOL EmptyDirectory(LPCTSTR szPath, BOOL bDeleteDesktopIni = FALSE, BOOL bWipeIndexDat = FALSE);
BOOL IsWindowsNT();
BOOL IsWindows2k();
BOOL GetUserSid(PSID* ppSid);
void GetSidString(PSID pSid, LPTSTR szBuffer);
BOOL GetOldSD(HKEY hKey, LPCTSTR pszSubKey, BYTE** pSD);
BOOL CreateNewSD(PSID pSid, SECURITY_DESCRIPTOR* pSD, PACL* ppDacl);
BOOL RegSetPrivilege(HKEY hKey, LPCTSTR pszSubKey, SECURITY_DESCRIPTOR* pSD, BOOL bRecursive);
BOOL WipeFile(LPCTSTR szDir, LPCTSTR szFile);
TCHAR szPath[MAX_PATH];
DeleteUrlCache(File);
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_INTERNET_CACHE, FALSE))
EmptyDirectory(szPath);
替代方案:直接呼叫 WinInet API 列舉並刪除快取項目(略)。
TCHAR szPath[MAX_PATH];
DeleteUrlCache(Cookie);
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_COOKIES, FALSE))
EmptyDirectory(szPath);
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Internet Explorer\\TypedURLs"));
涉及受保護的儲存體,需先取得使用者 SID、調整登錄權限後刪除:
// 核心邏輯:NT/2000/XP 需修改安全描述子,Win9x 直接用使用者名稱
// 詳細程式碼請見原文,關鍵路徑:
// Software\\Microsoft\\Protected Storage System Provider\\<SID>\\Data\\e161255a-37c3-11d2-bcaa-00c04fd929db
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Internet Explorer\\IntelliForms"));
TCHAR szPath[MAX_PATH];
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_FAVORITES, FALSE))
EmptyDirectory(szPath);
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\RAS Autodial\\Addresses"));
TCHAR szPath[MAX_PATH];
if (GetTempPath(MAX_PATH, szPath))
EmptyDirectory(szPath, TRUE);
SHEmptyRecycleBin(NULL, NULL,
SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU"));
TCHAR szPath[MAX_PATH];
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_RECENT, FALSE))
EmptyDirectory(szPath);
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs"));
SHDeleteValue(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
_T("DefaultUserName"));
SHDeleteValue(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
_T("AltDefaultUserName"));
SHDeleteValue(HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Winlogon"),
_T("DefaultUserName"));
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Doc Find Spec MRU"));
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Internet Explorer\\Explorer Bars\\{C4EE31F3-4768-11D2-BE5C-00A0C9A83DA1}\\ContainingTextMRU"));
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Internet Explorer\\Explorer Bars\\{C4EE31F3-4768-11D2-BE5C-00A0C9A83DA1}\\FilesNamedMRU"));
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FindComputerMRU"));
SHDeleteKey(HKEY_CURRENT_USER,
_T("Software\\Microsoft\\Internet Explorer\\Explorer Bars\\{C4EE31F3-4768-11D2-BE5C-00A0C9A83DA1}\\ComputerNameMRU"));
TCHAR szPath[MAX_PATH];
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_NETHOOD, FALSE))
EmptyDirectory(szPath);
CString sKey;
for (int i = 1; i <= 8; i++) {
sKey.Format(_T("Machine%d"), i);
SHDeleteValue(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Telnet"), sKey);
sKey.Format(_T("Service%d"), i);
SHDeleteValue(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Telnet"), sKey);
sKey.Format(_T("TermType%d"), i);
SHDeleteValue(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Telnet"), sKey);
}
SHDeleteValue(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Telnet"), _T("LastMachine"));
SHDeleteValue(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Telnet"), _T("LastService"));
SHDeleteValue(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Telnet"), _T("LastTermType"));
方法一:使用 IUrlHistoryStg2::ClearHistory()
#include <SHLGUID.H>
HRESULT ClearHistory() {
HRESULT hr;
CoInitialize(NULL);
IUrlHistoryStg2* pUrlHistoryStg2 = NULL;
hr = CoCreateInstance(CLSID_CUrlHistory, NULL, CLSCTX_INPROC_SERVER,
IID_IUrlHistoryStg2, (void**)&pUrlHistoryStg2);
if (SUCCEEDED(hr)) {
hr = pUrlHistoryStg2->ClearHistory();
pUrlHistoryStg2->Release();
}
CoUninitialize();
return hr;
}
方法二:直接刪除 History 資料夾內容(不完美但有效)
TCHAR szPath[MAX_PATH];
GetWindowsDirectory(szPath, MAX_PATH);
_tcscat(szPath, _T("\\History"));
EmptyDirectory(szPath, FALSE, TRUE);
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_HISTORY, FALSE))
EmptyDirectory(szPath, FALSE, TRUE);
至此,一個功能完整的歷史記錄清除工具已實作完成。細節請參考作者提供的完整原始碼。此工具在 Windows 98/2000/XP 下測試通過,對於維護共用電腦隱私極具實用價值。
作者:陳亮 (cl7986@etang.com)