using System;
using System.Runtime.InteropServices;
namespace TimeFound.CTD.ResourceManager
{
///
#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;
///
///
#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 加载数据
///
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
}
}