using System;
using System.Runtime.InteropServices;
namespace TimeFound.CTD.ResourceManager
{
///
/// IECache 的摘要说明。
///
public class IECache
{
public IECache()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region 引入所需要的Dll
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct INTERNET_CACHE_ENTRY_INFO
{
public int dwStructSize;
public IntPtr lpszSourceUrlName;
public IntPtr lpszLocalFileName;
public int CacheEntryType;
public int dwUseCount;
public int dwHitRate;
public int dwSizeLow;
public int dwSizeHigh;
public FILETIME LastModifiedTime;
public FILETIME ExpireTime;
public FILETIME LastAccessTime;
public FILETIME LastSyncTime;
public IntPtr lpHeaderInfo;
public int dwHeaderInfoSize;
public IntPtr lpszFileExtension;
public int dwExemptDelta;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SYSTEMTIME
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
[DllImport("kernel32.dll",
SetLastError = true,
CharSet = CharSet.Auto)
]
private static extern int FileTimeToSystemTime(
IntPtr lpFileTime,
IntPtr lpSystemTime);
[DllImport("wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "FindFirstUrlCacheGroup",
CallingConvention = CallingConvention.StdCall)
]
private static extern IntPtr FindFirstUrlCacheGroup(
int dwFlags,
int dwFilter,
IntPtr lpSearchCondition,
int dwSearchCondition,
ref long lpGroupId,
IntPtr lpReserved);
[DllImport("wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "FindNextUrlCacheGroup",
CallingConvention = CallingConvention.StdCall)
]
private static extern bool FindNextUrlCacheGroup(
IntPtr hFind,
ref long lpGroupId,
IntPtr lpReserved);
[DllImport("wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "DeleteUrlCacheGroup",
CallingConvention = CallingConvention.StdCall)
]
private static extern bool DeleteUrlCacheGroup(
long GroupId,
int dwFlags,
IntPtr lpReserved);
[DllImport("wininet.dll",
SetLastError = true,
CharSet = CharSet.Auto)
]
private static extern IntPtr FindFirstUrlCacheEntry(
[MarshalAs(UnmanagedType.LPTStr)] string UrlSearchPattern,
IntPtr lpFirstCacheEntryInfo,
ref int lpdwFirstCacheEntryInfoBufferSize);
[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool FindNextUrlCacheEntry(
IntPtr hEnumHandle,
IntPtr lpNextCacheEntryInfo,
ref int lpdwNextCacheEntryInfoBufferSize);
[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool GetUrlCacheEntryInfo(
[MarshalAs(UnmanagedType.LPTStr)] string lpszUrlName,
IntPtr lpCacheEntryInfo,
ref int lpdwCacheEntryInfoBufferSize
);
[DllImport("wininet.dll")]
private static extern bool FindCloseUrlCache(IntPtr hEnumHandle);
[DllImport("wininet",
SetLastError = true,
CharSet = CharSet.Auto,
EntryPoint = "DeleteUrlCacheEntryA",
CallingConvention = CallingConvention.StdCall)
]
private static extern bool DeleteUrlCacheEntry(
IntPtr lpszUrlName);
const int ERROR_NO_MORE_ITEMS = 259;
///
/// Retrieves the flags, type, and disk quota attributes of the cache group. This is used by the GetUrlCacheGroupAttribute function.
///
const int CACHEGROUP_ATTRIBUTE_BASIC = 0x00000001;
///
/// Sets or retrieves the flags associated with the cache group. This is used by the GetUrlCacheGroupAttribute and SetUrlCacheGroupAttribute functions.
///
const int CACHEGROUP_ATTRIBUTE_FLAG = 0x00000002;
///
/// Retrieves all the attributes of the cache group. This is used by the GetUrlCacheGroupAttribute function.
///
const uint CACHEGROUP_ATTRIBUTE_GET_ALL = 0xffffffff;
///
/// Sets or retrieves the group name of the cache group. This is used by the GetUrlCacheGroupAttribute and SetUrlCacheGroupAttribute functions.
///
const int CACHEGROUP_ATTRIBUTE_GROUPNAME = 0x000000010;
///
/// Sets or retrieves the disk quota associated with the cache group. This is used by the GetUrlCacheGroupAttribute and SetUrlCacheGroupAttribute functions.
///
const int CACHEGROUP_ATTRIBUTE_QUOTA = 0x00000008;
///
/// Sets or retrieves the group owner storage associated with the cache group. This is used by the GetUrlCacheGroupAttribute and SetUrlCacheGroupAttribute functions.
///
const int CACHEGROUP_ATTRIBUTE_STORAGE = 0x00000020;
///
/// Sets or retrieves the cache group type. This is used by the GetUrlCacheGroupAttribute and SetUrlCacheGroupAttribute functions.
///
const int CACHEGROUP_ATTRIBUTE_TYPE = 0x00000004;
///
/// Indicates that all the cache entries associated with the cache group should be deleted, unless the entry belongs to another cache group.
///
const int CACHEGROUP_FLAG_FLUSHURL_ONDELETE = 0x00000002;
///
/// Indicates that the function should only create a unique GROUPID for the cache group and not create the actual group.
///
const int CACHEGROUP_FLAG_GIDONLY = 0x00000004;
///
/// Indicates that the cache group cannot be purged.
///
const int CACHEGROUP_FLAG_NONPURGEABLE = 0x00000001;
///
/// Sets the type, disk quota, group name, and owner storage attributes of the cache group. This is used by the SetUrlCacheGroupAttribute function.
///
const int CACHEGROUP_READWRITE_MASK = 0x0000003c;
///
/// Indicates that all of the cache groups in the user's system should be enumerated.
///
const int CACHEGROUP_SEARCH_ALL = 0x00000000;
///
/// Not currently implemented.
///
const int CACHEGROUP_SEARCH_BYURL = 0x00000001;
///
/// Indicates that the cache group type is invalid.
///
const int CACHEGROUP_TYPE_INVALID = 0x00000001;
///
/// Length of the group owner storage array.
///
const int GROUP_OWNER_STORAGE_SIZE = 0x00000004;
///
/// Maximum number of characters allowed for a cache group name.
///
const int GROUPNAME_MAX_LENGTH = 0x00000078;
#endregion
#region FileTimeToSystemTime
private string FILETIMEtoDataTime(FILETIME time)
{
IntPtr filetime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FILETIME)));
IntPtr systime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SYSTEMTIME)));
Marshal.StructureToPtr(time, filetime, true);
FileTimeToSystemTime(filetime, systime);
SYSTEMTIME st = (SYSTEMTIME) Marshal.PtrToStructure(systime, typeof(SYSTEMTIME));
string Time = st.wYear.ToString() + "." + st.wMonth.ToString() + "." + st.wDay.ToString() + "." + st.wHour.ToString() + "." + st.wMinute.ToString() + "." + st.wSecond.ToString();
return Time;
}
#endregion
#region 加载数据
///
/// 获得指定的URL的cache文件名
///
/// URL
/// 如果不存在该cache,返回空字符串
public string GetURLCacheFileName(string URL)
{
string s = "";
int nNeeded = 0, nBufSize;
IntPtr buf;
INTERNET_CACHE_ENTRY_INFO CacheItem;
FindFirstUrlCacheEntry(null, IntPtr.Zero, ref nNeeded);
if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
return s;
nBufSize = nNeeded;
buf = Marshal.AllocHGlobal(nBufSize);
GetUrlCacheEntryInfo(URL, buf, ref nNeeded);
try
{
CacheItem = (INTERNET_CACHE_ENTRY_INFO) Marshal.PtrToStructure(buf, typeof(INTERNET_CACHE_ENTRY_INFO));
s = Marshal.PtrToStringAuto(CacheItem.lpszLocalFileName);
/*
以下这一段儿写的有些弱智。。。。但是没有办法。。。。
*不知道为什么,通过上面的方法取出来的文件的Cache路径,
* 有时候是乱码,有时候用PtrToStringAnsi可是又正常。。。。。
* 唉,所以只能用这个笨办法。。。。
*/
if (s.IndexOf("Temporary Internet Files") == -1)
s = Marshal.PtrToStringAnsi(CacheItem.lpszLocalFileName);
if (s.IndexOf("Temporary Internet Files") == -1)
s = Marshal.PtrToStringBSTR(CacheItem.lpszLocalFileName);
if (s.IndexOf("Temporary Internet Files") == -1)
s = Marshal.PtrToStringUni(CacheItem.lpszLocalFileName);
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
Marshal.FreeHGlobal(buf);
return s;
}
public void GetCacheFile()
{
int nNeeded = 0, nBufSize;
IntPtr buf;
INTERNET_CACHE_ENTRY_INFO CacheItem;
IntPtr hEnum;
bool r;
FindFirstUrlCacheEntry(null, IntPtr.Zero, ref nNeeded);
if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
return;
nBufSize = nNeeded;
buf = Marshal.AllocHGlobal(nBufSize);
hEnum = FindFirstUrlCacheEntry(null, buf, ref nNeeded);
while (true)
{
CacheItem = (INTERNET_CACHE_ENTRY_INFO) Marshal.PtrToStructure(buf,
typeof(INTERNET_CACHE_ENTRY_INFO));
string modifiedTime = FILETIMEtoDataTime(CacheItem.LastModifiedTime);
string expireTime = FILETIMEtoDataTime(CacheItem.ExpireTime);
string accessTime = FILETIMEtoDataTime(CacheItem.LastAccessTime);
string syncTime = FILETIMEtoDataTime(CacheItem.LastSyncTime);
string s;
#region 获得数据
try
{
s = Marshal.PtrToStringAuto(CacheItem.lpszSourceUrlName)
+ System.Environment.NewLine
+ " ===> " + Marshal.PtrToStringAuto(CacheItem.lpszLocalFileName)
+ System.Environment.NewLine
+ " ==> " + Marshal.PtrToStringAuto(CacheItem.lpHeaderInfo)
+ System.Environment.NewLine
+ Marshal.PtrToStringAuto(CacheItem.lpszFileExtension);
Console.WriteLine(s);
}
catch
{
}
#endregion
nNeeded = nBufSize;
r = FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);
if (!r && Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
break;
if (!r && nNeeded > nBufSize)
{
nBufSize = nNeeded;
buf = Marshal.ReAllocHGlobal(buf, (IntPtr) nBufSize);
FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);
}
}
Marshal.FreeHGlobal(buf);
}
#endregion
}
}