C#清除本地cookie代码
最近突发奇想,想做一个刷IP的软件,由于一直使用C#编程,基本框架做起来相当简单,唯一比较郁闷的是c#中没有现成的清除本地cookie和IE临时文件夹的方法(用来清除统计代码的cookies,^_^很邪恶吧),话说回来,c#好用,可惜权限比较低,一些涉及系统内部的操作,只好使用c++和c#混合编程的方法了。
本文中涉及到的dll文件下载
在window xp SP3+vs2008 中测试成功~
如果直接用c++写dll,在c#中调用起来比较麻烦,我选择使用ATL的方式编写一个com库,写好后直接在c#或者其他编程语言(VB,Delphi等)中直接引用库就可以了~
以下代码提供了几个封装好的方法:
- ClearCookie 清除cookie
- ClearInternetTempFile 清除Temporary Internet Files中的临时文件
- ClearSystemTemp 清除系统缓存
- ClearIEUrlHistory 清除IE地址栏历史记录
- ClearAutoFormHistory 清除自动表单记录
- ClearAutoPasswordHistory 清除自动密码记录
- ClearFavoriteFolder 清理收藏夹
- ClearAutoRASHistory 清除ADSL拨号历史记录
随后添加一个ATL 简单对象和一个C++类,ATL对象用来为c#提供接口,c++类则存放基本算法代码。
c++代码中编写了一些辅助函数,用于在ATL中调用
#include "StdAfx.h" #include "innerapi.h" innerapi::innerapi(void) { } innerapi::~innerapi(void) { } BOOL innerapi::EmptyDirectory(LPCTSTR szPath, BOOL bDeleteDesktopIni, BOOL bWipeIndexDat) { WIN32_FIND_DATA wfd; HANDLE hFind; CString sFullPath; CString sFindFilter; DWORD dwAttributes = 0; sFindFilter = szPath; sFindFilter += _T("\\*.*"); if ((hFind = FindFirstFile(sFindFilter, &wfd)) == INVALID_HANDLE_VALUE) { return FALSE; } do { if (_tcscmp(wfd.cFileName, _T(".")) == 0 || _tcscmp(wfd.cFileName, _T("..")) == 0 || (bDeleteDesktopIni == FALSE && _tcsicmp(wfd.cFileName, _T("desktop.ini")) == 0)) { continue; } sFullPath = szPath; sFullPath += _T('\\'); sFullPath += wfd.cFileName; //去掉只读属性 dwAttributes = GetFileAttributes(sFullPath); if (dwAttributes & FILE_ATTRIBUTE_READONLY) { dwAttributes &= ~FILE_ATTRIBUTE_READONLY; SetFileAttributes(sFullPath, dwAttributes); } if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { EmptyDirectory(sFullPath, bDeleteDesktopIni, bWipeIndexDat); RemoveDirectory(sFullPath); } else { if (bWipeIndexDat && _tcsicmp(wfd.cFileName, _T("index.dat")) == 0) { WipeFile(szPath, wfd.cFileName); } DeleteFile(sFullPath); } } while (FindNextFile(hFind, &wfd)); FindClose(hFind); return TRUE; } BOOL innerapi::WipeFile(LPCTSTR szDir, LPCTSTR szFile) { CString sPath; HANDLE hFile; DWORD dwSize; DWORD dwWrite; char sZero[SWEEP_BUFFER_SIZE]; memset(sZero, 0, SWEEP_BUFFER_SIZE); sPath = szDir; sPath += _T('\\'); sPath += szFile; hFile = CreateFile(sPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return FALSE; } dwSize = GetFileSize(hFile, NULL); //skip file header (actually, I don't know the file format of index.dat) dwSize -= 64; SetFilePointer(hFile, 64, NULL, FILE_BEGIN); while (dwSize > 0) { if (dwSize > SWEEP_BUFFER_SIZE) { WriteFile(hFile, sZero, SWEEP_BUFFER_SIZE, &dwWrite, NULL); dwSize -= SWEEP_BUFFER_SIZE; } else { WriteFile(hFile, sZero, dwSize, &dwWrite, NULL); break; } } CloseHandle(hFile); return TRUE; } BOOL innerapi::DeleteUrlCache(DEL_CACHE_TYPE type) { BOOL bRet = FALSE; HANDLE hEntry; LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL; DWORD dwEntrySize; //delete the files dwEntrySize = 0; hEntry = FindFirstUrlCacheEntry(NULL, NULL, &dwEntrySize); lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize]; hEntry = FindFirstUrlCacheEntry(NULL, lpCacheEntry, &dwEntrySize); if (!hEntry) { goto cleanup; } do { if (type == File && !(lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY)) { DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName); } else if (type == Cookie && (lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY)) { DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName); } dwEntrySize = 0; FindNextUrlCacheEntry(hEntry, NULL, &dwEntrySize); delete [] lpCacheEntry; lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize]; } while (FindNextUrlCacheEntry(hEntry, lpCacheEntry, &dwEntrySize)); bRet = TRUE; cleanup: if (lpCacheEntry) { delete [] lpCacheEntry; } return bRet; } BOOL innerapi::RegSetPrivilege(HKEY hKey, LPCTSTR pszSubKey, SECURITY_DESCRIPTOR* pSD, BOOL bRecursive) { BOOL bRet = FALSE; HKEY hSubKey = NULL; LONG lRetCode; LPTSTR pszKeyName = NULL;; DWORD dwSubKeyCnt; DWORD dwMaxSubKey; DWORD dwValueCnt; DWORD dwMaxValueName; DWORD dwMaxValueData; DWORD i; if (!pszSubKey) goto cleanup; // open the key for WRITE_DAC access lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, WRITE_DAC, &hSubKey); if(lRetCode != ERROR_SUCCESS) goto cleanup; // apply the security descriptor to the registry key lRetCode = RegSetKeySecurity(hSubKey, (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, pSD); if( lRetCode != ERROR_SUCCESS ) goto cleanup; if (bRecursive) { // reopen the key for KEY_READ access RegCloseKey(hSubKey); hSubKey = NULL; lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, KEY_READ, &hSubKey); if(lRetCode != ERROR_SUCCESS) goto cleanup; // first get an info about this subkey ... lRetCode = RegQueryInfoKey(hSubKey, 0, 0, 0, &dwSubKeyCnt, &dwMaxSubKey, 0, &dwValueCnt, &dwMaxValueName, &dwMaxValueData, 0, 0); if( lRetCode != ERROR_SUCCESS ) goto cleanup; // enumerate the subkeys and call RegTreeWalk() recursivly pszKeyName = new TCHAR [MAX_PATH + 1]; for (i=0 ; i<dwSubKeyCnt; i++) { lRetCode = RegEnumKey(hSubKey, i, pszKeyName, MAX_PATH + 1); if(lRetCode == ERROR_SUCCESS) { RegSetPrivilege(hSubKey, pszKeyName, pSD, TRUE); } else if(lRetCode == ERROR_NO_MORE_ITEMS) { break; } } delete [] pszKeyName ; } bRet = TRUE; // indicate success cleanup: if (hSubKey) { RegCloseKey(hSubKey); } return bRet; } //判断系统类型 BOOL innerapi::IsWindowsNT() { BOOL bRet = FALSE; BOOL bOsVersionInfoEx; OSVERSIONINFOEX osvi; // Try calling GetVersionEx using the OSVERSIONINFOEX structure, // If that fails, try using the OSVERSIONINFO structure. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) { // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO. osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) return bRet; } if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion <= 4) { bRet = TRUE; } return bRet; } BOOL innerapi::IsWindows2k() { BOOL bRet = FALSE; BOOL bOsVersionInfoEx; OSVERSIONINFOEX osvi; // Try calling GetVersionEx using the OSVERSIONINFOEX structure, // If that fails, try using the OSVERSIONINFO structure. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) { // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO. osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) return bRet; } if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion >= 5) { bRet = TRUE; } return bRet; } BOOL innerapi::GetUserSid(PSID* ppSid) { HANDLE hToken; BOOL bRes; DWORD cbBuffer, cbRequired; PTOKEN_USER pUserInfo; // The User's SID can be obtained from the process token bRes = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken); if (FALSE == bRes) { return FALSE; } // Set buffer size to 0 for first call to determine // the size of buffer we need. cbBuffer = 0; bRes = GetTokenInformation(hToken, TokenUser, NULL, cbBuffer, &cbRequired); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return FALSE; } // Allocate a buffer for our token user data cbBuffer = cbRequired; pUserInfo = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbBuffer); if (NULL == pUserInfo) { return FALSE; } // Make the "real" call bRes = GetTokenInformation(hToken, TokenUser, pUserInfo, cbBuffer, &cbRequired); if (FALSE == bRes) { return FALSE; } // Make another copy of the SID for the return value cbBuffer = GetLengthSid(pUserInfo->User.Sid); *ppSid = (PSID) HeapAlloc(GetProcessHeap(), 0, cbBuffer); if (NULL == *ppSid) { return FALSE; } bRes = CopySid(cbBuffer, *ppSid, pUserInfo->User.Sid); if (FALSE == bRes) { HeapFree(GetProcessHeap(), 0, *ppSid); return FALSE; } bRes = HeapFree(GetProcessHeap(), 0, pUserInfo); return TRUE; } void innerapi::GetSidString(PSID pSid, LPTSTR szBuffer) { //convert SID to string SID_IDENTIFIER_AUTHORITY *psia = ::GetSidIdentifierAuthority( pSid ); DWORD dwTopAuthority = psia->Value[5]; _stprintf(szBuffer, _T("S-1-%lu"), dwTopAuthority); TCHAR szTemp[32]; int iSubAuthorityCount = *(GetSidSubAuthorityCount(pSid)); for (int i = 0; i<iSubAuthorityCount; i++) { DWORD dwSubAuthority = *(GetSidSubAuthority(pSid, i)); _stprintf(szTemp, _T("%lu"), dwSubAuthority); _tcscat(szBuffer, _T("-")); _tcscat(szBuffer, szTemp); } } BOOL innerapi::GetOldSD(HKEY hKey, LPCTSTR pszSubKey, BYTE** pSD) { BOOL bRet = FALSE; HKEY hNewKey = NULL; DWORD dwSize = 0; LONG lRetCode; *pSD = NULL; lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, READ_CONTROL, &hNewKey); if(lRetCode != ERROR_SUCCESS) goto cleanup; lRetCode = RegGetKeySecurity(hNewKey, (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, *pSD, &dwSize); if (lRetCode == ERROR_INSUFFICIENT_BUFFER) { *pSD = new BYTE[dwSize]; lRetCode = RegGetKeySecurity(hNewKey, (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, *pSD, &dwSize); if(lRetCode != ERROR_SUCCESS) { delete *pSD; *pSD = NULL; goto cleanup; } } else if (lRetCode != ERROR_SUCCESS) goto cleanup; bRet = TRUE; // indicate success cleanup: if (hNewKey) { RegCloseKey(hNewKey); } return bRet; } BOOL innerapi::CreateNewSD(PSID pSid, SECURITY_DESCRIPTOR* pSD, PACL* ppDacl) { BOOL bRet = FALSE; PSID pSystemSid = NULL; SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY; ACCESS_ALLOWED_ACE* pACE = NULL; DWORD dwAclSize; DWORD dwAceSize; // prepare a Sid representing local system account if(!AllocateAndInitializeSid(&sia, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid)) { goto cleanup; } // compute size of new acl dwAclSize = sizeof(ACL) + 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetLengthSid(pSid) + GetLengthSid(pSystemSid); // allocate storage for Acl *ppDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize); if(*ppDacl == NULL) goto cleanup; if(!InitializeAcl(*ppDacl, dwAclSize, ACL_REVISION)) goto cleanup; // if(!AddAccessAllowedAce(pDacl, ACL_REVISION, KEY_WRITE, pSid)) // goto cleanup; // add current user dwAceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid); pACE = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize); pACE->Mask = KEY_READ | KEY_WRITE | KEY_ALL_ACCESS; pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pACE->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE; pACE->Header.AceSize = dwAceSize; memcpy(&pACE->SidStart, pSid, GetLengthSid(pSid)); if (!AddAce(*ppDacl, ACL_REVISION, MAXDWORD, pACE, dwAceSize)) goto cleanup; // add local system account HeapFree(GetProcessHeap(), 0, pACE); pACE = NULL; dwAceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSystemSid); pACE = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize); pACE->Mask = KEY_READ | KEY_WRITE | KEY_ALL_ACCESS; pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pACE->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE; pACE->Header.AceSize = dwAceSize; memcpy(&pACE->SidStart, pSystemSid, GetLengthSid(pSystemSid)); if (!AddAce(*ppDacl, ACL_REVISION, MAXDWORD, pACE, dwAceSize)) goto cleanup; if(!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) goto cleanup; if(!SetSecurityDescriptorDacl(pSD, TRUE, *ppDacl, FALSE)) goto cleanup; bRet = TRUE; // indicate success cleanup: if(pACE != NULL) HeapFree(GetProcessHeap(), 0, pACE); if(pSystemSid != NULL) FreeSid(pSystemSid); return bRet; }
ATL中的代码
// histroy.cpp : Chistroy 的实现 #include "stdafx.h" #include "histroy.h" // Chistroy STDMETHODIMP Chistroy::ClearCookie(VARIANT_BOOL* ret) { // TODO: 在此添加实现代码 TCHAR szPath[MAX_PATH]; api.DeleteUrlCache(api.Cookie); if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_COOKIES, FALSE)) {//得到目录,并清空 api.EmptyDirectory(szPath); } return S_OK; } STDMETHODIMP Chistroy::ClearInternetTempFile(VARIANT_BOOL* ret) { // TODO: 在此添加实现代码 // //清internet临时文件 TCHAR szPath[MAX_PATH]; api.DeleteUrlCache(api.File); if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_INTERNET_CACHE, FALSE)) { //得到临时目录,并清空它. api.EmptyDirectory(szPath); } return S_OK; } STDMETHODIMP Chistroy::ClearSystemTemp(VARIANT_BOOL* ret) { // TODO: 在此添加实现代码 // //清系统临时文件夹 TCHAR szPath[MAX_PATH]; if (GetTempPath(MAX_PATH, szPath))//得到系统临时目录 { api.EmptyDirectory(szPath, TRUE); } return S_OK; } STDMETHODIMP Chistroy::ClearIEUrlHistory(VARIANT_BOOL* ret) { //浏览器地址栏历史地址的清除 SHDeleteKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\TypedURLs")); return S_OK; } STDMETHODIMP Chistroy::ClearAutoFormHistory(VARIANT_BOOL* ret) { // 清除表单自动完成历史记录 CString sKey; DWORD dwRet; if (api.IsWindows2k() || api.IsWindowsNT())//先判断系统 { CString sBaseKey; SECURITY_DESCRIPTOR NewSD; BYTE* pOldSD; PACL pDacl = NULL; PSID pSid = NULL; TCHAR szSid[256]; if (api.GetUserSid(&pSid)) { //get the hiden key name api.GetSidString(pSid, szSid); sKey = _T("Software\\Microsoft\\Protected Storage System Provider\\"); sKey += szSid; //get old SD sBaseKey = sKey; api.GetOldSD(HKEY_CURRENT_USER, sBaseKey, &pOldSD); //set new SD and then clear if (api.CreateNewSD(pSid, &NewSD, &pDacl)) { api.RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, FALSE); sKey += _T("\\Data"); api.RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, FALSE); sKey += _T("\\e161255a-37c3-11d2-bcaa-00c04fd929db"); api.RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, TRUE); dwRet = SHDeleteKey(HKEY_CURRENT_USER, sKey); } if (pDacl != NULL) HeapFree(GetProcessHeap(), 0, pDacl); //restore old SD if (pOldSD) { api.RegSetPrivilege(HKEY_CURRENT_USER, sBaseKey, (SECURITY_DESCRIPTOR*)pOldSD, FALSE); delete pOldSD; } } if (pSid) HeapFree(GetProcessHeap(), 0, pSid); } //win9x DWORD dwSize = MAX_PATH; TCHAR szUserName[MAX_PATH]; GetUserName(szUserName, &dwSize); sKey = _T("Software\\Microsoft\\Protected Storage System Provider\\"); sKey += szUserName; sKey += _T("\\Data\\e161255a-37c3-11d2-bcaa-00c04fd929db"); dwRet = SHDeleteKey(HKEY_LOCAL_MACHINE, sKey); return S_OK; } STDMETHODIMP Chistroy::ClearAutoPasswordHistory(VARIANT_BOOL* ret) { // 清除自动密码历史记录 SHDeleteKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Explorer\\IntelliForms")); return S_OK; } STDMETHODIMP Chistroy::ClearFavoriteFolder(VARIANT_BOOL* ret) { //清收藏夹中的内容 TCHAR szPath[MAX_PATH]; if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_FAVORITES, FALSE)) { //得到目录,并清空 api.EmptyDirectory(szPath); } return S_OK; } STDMETHODIMP Chistroy::ClearAutoRASHistory(VARIANT_BOOL* ret) { // 清RAS自动拨号历史记录 SHDeleteKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\RAS Autodial\\Addresses")); return S_OK; }
可以在c#中直接调用就可以了
最后提供一个dll文件下载
怎么添加引用都添加不成功啊?报错:Please make sure that the file is accessible,and that it is a valid assembly or COM component
已经解决了
那就好^_^
您好,我想请问一下,这个dll如何在c#中使用啊,请高指教!
c#中直接添加引用就可以了
我想在C#里加reference,但添加不成功, 报错:Please make sure that the file is accessible,and that it is a valid assembly or COM component.
Shinely, 怎么做的阿???
要先注册控件滴^_^
请问下,添加成功后,在自己写的程序里,应该怎么用呢?本人是菜鸟,请多指教,谢谢
需要在Visual Studio的项目中点击“引用”在对话框中浏览选择指定dll文件就可以了。
额 我的意思是 添加引用 成功后, 怎样在我写的代码里使用 你封装好的那些方法,能否请你指导下具体的步骤,谢谢拉
呵呵,用法很简单啦,我已经更新了文章,你看下最后一张图,如果无法引用请使用regsvr32注册一下控件
谢谢 博主,已经会用了,无以为报,就帮你点点广告啦,呵呵
怎么引用不起,报错。 regsvr32注册也不行。我是win10,VS2015。
版本高了,用2010,win7
cookies删不掉啊