自从Windows 2000采用了动态缓存目录的保护措施以来,通常用原来的方法在删除系统自带游戏几秒后,游戏又可以使用了。本文介绍了在Visual Studio 2005环境下进行C#编程,来实现显示DllCache目录下的文件,并删除Windows 2000 pro系统自带的四个游戏。
一、界面设计
新建Windows应用程序,在出现的form中添加TreeView、ListView和Button控件各一个,调整到适当的大小,改变button1的text为“删除系统自带程序”,将listview1的view项设置为detail,其余不变。添加三个imagelist控件,分别改名为TreeImageList、TreeViewImageList和ListViewImageList,用于存放引用自系统shell32.dll中的图标。
二、显示DllCache目录及其下面的文件
1.添加使用命名空间和文件结构信息
-
using System.IO;
-
using System.Runtime.InteropServices;
-
using System.Reflection;
2.添加文件结构信息,调用Windows API中的提取图标函数和获取系统路径函数,并构造自定义的提取图标函数。
-
[StructLayout(LayoutKind.Sequential)] 0
-
public struct SHFILEINFO
-
{ public IntPtr hIcon;
-
public int iIcon;
-
public uint dwAttributes;
-
public char szDisplayName;
-
public char szTypeName; }
-
private System.Windows.Forms.ImageList TreeImageList;
-
//获取图标
-
[DllImport("Shell32.dll")]
-
public static extern int ExtractIcon(IntPtr h, string strx, int ii);
-
// 获取系统路径
-
[DllImport("Kernel32.dll" ,CharSet = CharSet.Auto)]
-
public static extern Int32 GetSystemDirectory(StringBuilder WinDir, Int32 usize);
-
//构造自定义提取图标函数
-
protected virtual Icon myExtractIcon(string FileName, int iIndex)
-
{ try
-
{ IntPtr hIcon = (IntPtr) ExtractIcon(this.Handle, FileName, iIndex);
-
if (!hIcon.Equals(null))
-
{ Icon icon = Icon.FromHandle(hIcon);
-
return icon; }
-
}
-
catch (Exception ex)
-
{ MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error); }
-
return null;
-
}
3.在Form构造函数中添加获取图标信息,图标取自shell32.dll。
-
Icon ic0 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 15);
-
TreeImageList.Images.Add(ic0);
-
Icon ic1 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 5);
-
TreeImageList.Images.Add(ic1);
-
Icon ic2 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 7);
-
TreeImageList.Images.Add(ic2);
-
Icon ic3 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 11);
-
TreeImageList.Images.Add(ic3);
-
Icon ic4 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 3);
-
TreeImageList.Images.Add(ic4);
-
Icon ic5 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 4);
-
TreeImageList.Images.Add(ic5);
-
Icon ic6 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 101);
-
TreeImageList.Images.Add(ic6);
-
Icon ic7 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 51);
4.在TreeView1中显示当前系统盘符和文件目录树
(1) 声明公共变量。
-
public const int nChars = 128;
-
public StringBuilder Buff = new StringBuilder(nChars);
(2) 在Form构造函数中添加下列语句,用于添加根节点。
-
GetSystemDirectory(Buff, nChars);
-
Buff.Remove(3, Buff.Length - 3);
-
TreeNode RootNode = new TreeNode(Buff.ToString(), 0, 0);
-
treeView1.BeginUpdate();
-
treeView1.Nodes.Clear();
-
treeView1.Nodes.Add(RootNode);
-
treeView1.ImageList = TreeImageList;
-
treeView1.EndUpdate();
(3) 选中在TreeView1的某一节点后,执行AfterSelect事件中的语句,要求能够实现打开此目录的下级目录,并将下级目录添加入TreeView1中。
-
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
-
{ AddDirectories(e.Node); }//e.Node为当前打开的节点
-
void AddDirectories(TreeNode tn)
-
{
-
tn.Nodes.Clear();
-
string strPath = tn.FullPath;
-
DirectoryInfo dirinfo = new DirectoryInfo(strPath); //获得当前目录
-
DirectoryInfo[] adirinfo;
-
try{ adirinfo = dirinfo.GetDirectories(); }
-
catch { return; }
-
int iImageIndex = 4; int iSelectedIndex = 5;
-
foreach (DirectoryInfo di in adirinfo)
-
{
-
if (di.Name == "RECYCLER" || di.Name == "RECYCLED" || di.Name == "Recycled")
-
{ iImageIndex = 6; iSelectedIndex = 6; }
-
else
-
{ iImageIndex = 4; iSelectedIndex = 5; }
-
TreeNode tnDir = new TreeNode(di.Name, iImageIndex, iSelectedIndex);
-
tn.Nodes.Add(tnDir);
-
}
-
}
5.LiseView中显示当前目录(选中的节点)下的文件和下级目录。
(1)添加公共变量。
-
public string strFilePath = "";
(2)构造自定义函数,用于显示文件的图标。
-
protected virtual void SetIcon(ImageList imageList, string FileName, bool tf)
-
{ SHFILEINFO fi = new SHFILEINFO();
-
if (tf == true)
-
{ int iTotal = (int)SHGetFileInfo(FileName, 0, ref fi, 100, 16640);
-
try
-
{ if (iTotal > 0)
-
{ Icon ic = Icon.FromHandle(fi.hIcon); //提取文件自带的小图标
-
imageList.Images.Add(ic); }
-
}
-
catch (Exception ex)
-
{ MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error); }
-
}
-
else
-
{ int iTotal = (int)SHGetFileInfo(FileName, 0, ref fi, 100, 257);
-
try
-
{ if (iTotal > 0)
-
{ Icon ic = Icon.FromHandle(fi.hIcon);
-
imageList.Images.Add(ic); }
-
}
-
catch (Exception ex)
-
{ MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error);
-
}
-
}
-
}
(3) 构造自定义函数,用于显示选中的基本节点下的文件和下级目录。
-
protected virtual void InitList(TreeNode tn)
-
{ this.Cursor = Cursors.WaitCursor;
-
this.ListViewImageList.Images.Clear();
-
listView1.SmallImageList = this.ListViewImageList;
-
Icon ic0 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 3);
-
this.ListViewImageList.Images.Add(ic0);
-
listView1.Clear();
-
//设置列表框的表头
-
listView1.Columns.Add("文件(夹)名", 160, HorizontalAlignment.Left);
-
listView1.Columns.Add("扩展名", 100, HorizontalAlignment.Center);
-
listView1.Columns.Add("文件大小", 120, HorizontalAlignment.Left);
-
listView1.Columns.Add("创建时间", 120, HorizontalAlignment.Left);
-
listView1.Columns.Add("访问时间", 200, HorizontalAlignment.Left);
-
listView1.Columns.Add("上级文件夹", 400, HorizontalAlignment.Left);
-
string strPath = tn.FullPath;
-
//获得当前目录下的所有文件
-
DirectoryInfo curDir = new DirectoryInfo(strPath);//创建目录对象。
-
FileInfo[] dirFiles;
-
try { dirFiles = curDir.GetFiles(); }
-
catch { return; }
-
string[] arrSubItem = new string[10];
-
//文件的创建时间和访问时间。
-
int iCount = 0;
-
int iconIndex = 1;//用1,而不用0是要让过0号图标。
-
foreach (FileInfo fileInfo in dirFiles)
-
{ string strFileName = fileInfo.Name;
-
//如果不是文件pagefile.sys
-
if (!strFileName.Equals("pagefile.sys"))
-
{ arrSubItem[0] = strFileName;
-
if (fileInfo.Extension.Trim() == "")
-
arrSubItem[1] = "未知类型";
-
else
-
arrSubItem[1] = fileInfo.Extension.ToString();
-
arrSubItem[2] = fileInfo.Length + "字节";
-
arrSubItem[3] = fileInfo.CreationTime.ToString();
-
arrSubItem[4] = fileInfo.LastAccessTime.ToString();
-
arrSubItem[5] = fileInfo.Directory.ToString(); }
-
else
-
{ arrSubItem[1] = "未知扩展名";
-
arrSubItem[2] = "未知大小";
-
arrSubItem[3] = "未知日期";
-
arrSubItem[4] = "未知日期";
-
arrSubItem[5] = "未知上级文件夹"; }
-
//得到每个文件的图标
-
string str = fileInfo.FullName;
-
try { SetIcon(this.ListViewImageList, str, true); }
-
catch (Exception ex)
-
{ MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error); }
-
//插入列表项
-
ListViewItem LiItem = new ListViewItem(arrSubItem, iconIndex);
-
listView1.Items.Insert(iCount, LiItem);
-
iCount++;
-
iconIndex++;
-
}
-
strFilePath = strPath;
-
this.Cursor = Cursors.Arrow;
-
//以下是向列表框中插入目录,不是文件。获得当前目录下的各个子目录。
-
int iItem = 0;
-
DirectoryInfo Dir = new DirectoryInfo(strPath);
-
string[] arrDirectorySubItem = new string[10];
-
foreach (DirectoryInfo di in Dir.GetDirectories())
-
{ arrDirectorySubItem[0] = di.Name;
-
if (di.Extension.Trim() != "")
-
arrDirectorySubItem[1] = di.Extension;
-
else
-
{ arrDirectorySubItem[1] = "
-
";
-
arrDirectorySubItem[2] = "";
-
arrDirectorySubItem[3] = "";
-
arrDirectorySubItem[4] = "";
-
arrDirectorySubItem[5] = ""; }
-
ListViewItem LiItem = new ListViewItem(arrDirectorySubItem, 0);
-
listView1.Items.Insert(iItem, LiItem);
-
iItem++;
-
}
-
}
(4) 在构造自定treeView1_AfterSelect中的“AddDirectories(e.Node);”语句后添加下语句。
-
InitList(e.Node);
三、删除系统自带的四个游戏程序
(1)自定义函数,用于删除Windows2000的四个系统自带游戏
-
private void DelSystemFourGames()
-
{ string str="";
-
StringBuilder buff1 = new StringBuilder(nChars);
-
StringBuilder buff2 = new StringBuilder(nChars);
-
GetSystemDirectory(Buff, nChars);
-
Buff.Append("\\");
-
GetSystemDirectory(buff1, nChars);
-
buff1.Append("\\");
-
buff2=buff1;
-
str="sol.exe";
-
if(File_in_Directory(str, buff1.ToString()))
-
{ Buff.Append("sol.exe");//纸牌
-
buff2.Append("DllCache\\");
-
buff2.Append("sol.exe");
-
//执行删除文件,删除后的文件不出现在回收站中
-
File.Delete(Buff.ToString());
-
File.Delete(buff2.ToString());
-
Buff.Remove(Buff.Length - 7, 7);
-
//还原Buff的字符为system32\目录下,7是“sol.exe”的长度
-
buff2.Remove(buff2.Length - 7, 7);//类上,还原为dllcache\目录下
-
}
-
……
-
//省略了删除“空当接龙”和“扫雷”两个游戏的程序段因其内容同上,只不过改str = "freecell.exe"
-
//和str = "winmine.exe",以及Buff.Remove中的数字长度与相应的文件名长度一致。
-
// 删除windows XP中的蜘蛛“spider.exe”与上类同
-
GetSystemDirectory(Buff, nChars);
-
GetSystemDirectory(buff2, nChars);
-
buff2.Append("\\");
-
Buff.Remove(3, Buff.Length - 3); //反回到“盘符:\”状态
-
Buff.Append("Program Files\\WIndows NT\\Pinball");//桌上弹球
-
str = "pinball.exe";
-
if (File_in_Directory(str, Buff.ToString()))
-
{ DeleteDir(Buff.ToString());//删除目录
-
buff2.Append("DllCache\\");
-
buff2.Append("pinball.exe");
-
File.Delete(buff2.ToString());
-
}
-
}
(2)在button1_OnClick中调用自定义删除函数
-
DelSystemFourGames();
四、两个自定义函数
1.判断文件是否在指定的文件夹中
-
private bool File_in_Directory(string str1, string str2)
-
{
-
DirectoryInfo curDir = new DirectoryInfo(str2);//创建目录对象。
-
FileInfo[] dirFiles;
-
try
-
{ dirFiles = curDir.GetFiles(); }
-
catch
-
{ return false; }
-
foreach (FileInfo fileInfo in dirFiles)
-
{ if (fileInfo.Name == str1) return true; }
-
return false;
-
}
2.删除目录及目录下所有文件与子目录
-
public static void DeleteDir(string Path)
-
{ try
-
{ // 检查路径名是否以分割字符结束,如果不是则添加”\”分隔符
-
if (Path[Path.Length - 1] != Path.DirectorySeparatorChar)
-
Path += Path.DirectorySeparatorChar;
-
string[] fileList = Directory.GetFileSystemEntries(Path);
-
// 遍历所有的文件和目录
-
foreach (string file in fileList)
-
{
-
// 先将文件当作目录处理如果存在这个目录就递归Delete该目录下面的文件
-
if (Directory.Exists(file))
-
{
-
DeleteDir(Path + Path.GetFileName(file));
-
}
-
else // 否则直接Delete文件
-
{ //改变文件的只读属性
-
FileInfo fi = new FileInfo(file);
-
if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
-
fi.Attributes = FileAttributes.Normal;
-
File.Delete(Path + Path.GetFileName(file)); //删除文件
-
}
-
}
-
System.IO.Directory.Delete(Path, true); //删除文件夹
-
}
-
catch (Exception e)
-
{ MessageBox.Show(e.ToString()); }
-
}
附言:本文程序采用的是Visual Studio 2005 C#编写,所述代码均已在Windows 2000 pro/server中运行通过。
本文通过C#编程实现了删除Windows 2000系统自带游戏这个目标,并将微软为考虑自身安全的dllcache目录及其中的文件显示出来,希望能够对要了解这方面的相关人员有所帮助。
文章来源:http://www.hulian.top,转载请注明!