C#编程删除系统自带游戏

.NET技术    2011-05-10 14:08  

  自从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.添加使用命名空间和文件结构信息

   

   

  1. using System.IO;   
  2. using System.Runtime.InteropServices;   
  3. using System.Reflection;

   

  2.添加文件结构信息,调用Windows API中的提取图标函数和获取系统路径函数,并构造自定义的提取图标函数。

   

   

  1. [StructLayout(LayoutKind.Sequential)]  0 
  2. public struct SHFILEINFO   
  3. public IntPtr hIcon;   
  4. public int iIcon;   
  5. public uint dwAttributes;   
  6. public char szDisplayName;   
  7. public char szTypeName; }   
  8. private System.Windows.Forms.ImageList TreeImageList;   
  9. //获取图标   
  10. [DllImport("Shell32.dll")]   
  11. public static extern int ExtractIcon(IntPtr h, string strx, int ii);   
  12. // 获取系统路径   
  13. [DllImport("Kernel32.dll" ,CharSet = CharSet.Auto)]   
  14. public static extern Int32 GetSystemDirectory(StringBuilder WinDir, Int32 usize);   
  15. //构造自定义提取图标函数   
  16. protected virtual Icon myExtractIcon(string FileName, int iIndex)   
  17. try  
  18. { IntPtr hIcon = (IntPtr) ExtractIcon(this.Handle, FileName, iIndex);   
  19. if (!hIcon.Equals(null))   
  20. { Icon icon = Icon.FromHandle(hIcon);   
  21. return icon; }   
  22. }   
  23. catch (Exception ex)   
  24. { MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error); }   
  25. return null;   
  26. }  

   

  3.在Form构造函数中添加获取图标信息,图标取自shell32.dll。

   

   

  1. Icon ic0 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 15);   
  2. TreeImageList.Images.Add(ic0);   
  3. Icon ic1 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 5);   
  4. TreeImageList.Images.Add(ic1);   
  5. Icon ic2 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 7);   
  6. TreeImageList.Images.Add(ic2);   
  7. Icon ic3 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 11);   
  8. TreeImageList.Images.Add(ic3);   
  9. Icon ic4 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 3);   
  10. TreeImageList.Images.Add(ic4);   
  11. Icon ic5 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 4);   
  12. TreeImageList.Images.Add(ic5);   
  13. Icon ic6 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 101);   
  14. TreeImageList.Images.Add(ic6);   
  15. Icon ic7 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 51);    

   

  4.在TreeView1中显示当前系统盘符和文件目录树

  (1) 声明公共变量。

   

   

  1. public const int nChars = 128;   
  2. public StringBuilder Buff = new StringBuilder(nChars);

   

  (2) 在Form构造函数中添加下列语句,用于添加根节点。

   

   

  1. GetSystemDirectory(Buff, nChars);   
  2. Buff.Remove(3, Buff.Length - 3); 
  3. TreeNode RootNode = new TreeNode(Buff.ToString(), 0, 0);   
  4. treeView1.BeginUpdate();   
  5. treeView1.Nodes.Clear();   
  6. treeView1.Nodes.Add(RootNode);   
  7. treeView1.ImageList = TreeImageList;   
  8. treeView1.EndUpdate();  

   

  (3) 选中在TreeView1的某一节点后,执行AfterSelect事件中的语句,要求能够实现打开此目录的下级目录,并将下级目录添加入TreeView1中。

   

   

  1. private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)   
  2. { AddDirectories(e.Node); }//e.Node为当前打开的节点   
  3. void AddDirectories(TreeNode tn)   
  4. {   
  5. tn.Nodes.Clear();   
  6. string strPath = tn.FullPath;   
  7. DirectoryInfo dirinfo = new DirectoryInfo(strPath); //获得当前目录   
  8. DirectoryInfo[] adirinfo;   
  9. try{ adirinfo = dirinfo.GetDirectories(); }   
  10. catch { return; }   
  11. int iImageIndex = 4; int iSelectedIndex = 5;   
  12. foreach (DirectoryInfo di in adirinfo)   
  13. {   
  14. if (di.Name == "RECYCLER" || di.Name == "RECYCLED" || di.Name == "Recycled")   
  15. { iImageIndex = 6; iSelectedIndex = 6; }   
  16. else  
  17. { iImageIndex = 4; iSelectedIndex = 5; }   
  18. TreeNode tnDir = new TreeNode(di.Name, iImageIndex, iSelectedIndex);   
  19. tn.Nodes.Add(tnDir);   
  20. }   
  21. }    

   

  5.LiseView中显示当前目录(选中的节点)下的文件和下级目录。

  (1)添加公共变量。

   

   

  1. public string strFilePath = "";  

   

  (2)构造自定义函数,用于显示文件的图标。

   

   

  1. protected virtual void SetIcon(ImageList imageList, string FileName, bool tf)   
  2. { SHFILEINFO fi = new SHFILEINFO();   
  3. if (tf == true)   
  4. int iTotal = (int)SHGetFileInfo(FileName, 0, ref fi, 100, 16640);   
  5. try  
  6. if (iTotal > 0)   
  7. { Icon ic = Icon.FromHandle(fi.hIcon); //提取文件自带的小图标   
  8. imageList.Images.Add(ic); }   
  9. }   
  10. catch (Exception ex)   
  11. { MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error); }   
  12. }   
  13. else  
  14. int iTotal = (int)SHGetFileInfo(FileName, 0, ref fi, 100, 257);   
  15. try  
  16. if (iTotal > 0)   
  17. { Icon ic = Icon.FromHandle(fi.hIcon);   
  18. imageList.Images.Add(ic); }   
  19. }   
  20. catch (Exception ex)   
  21. { MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error);
  22. }   
  23. }   
  24. }    

   

  (3) 构造自定义函数,用于显示选中的基本节点下的文件和下级目录。

   

   

  1. protected virtual void InitList(TreeNode tn)   
  2. this.Cursor = Cursors.WaitCursor;   
  3. this.ListViewImageList.Images.Clear();   
  4. listView1.SmallImageList = this.ListViewImageList;   
  5. Icon ic0 = myExtractIcon("%SystemRoot%\\system32\\shell32.dll", 3);   
  6. this.ListViewImageList.Images.Add(ic0);   
  7. listView1.Clear();   
  8. //设置列表框的表头   
  9. listView1.Columns.Add("文件(夹)名", 160, HorizontalAlignment.Left);   
  10. listView1.Columns.Add("扩展名", 100, HorizontalAlignment.Center);   
  11. listView1.Columns.Add("文件大小", 120, HorizontalAlignment.Left);   
  12. listView1.Columns.Add("创建时间", 120, HorizontalAlignment.Left);   
  13. listView1.Columns.Add("访问时间", 200, HorizontalAlignment.Left);   
  14. listView1.Columns.Add("上级文件夹", 400, HorizontalAlignment.Left); 
  15. string strPath = tn.FullPath;   
  16. //获得当前目录下的所有文件   
  17. DirectoryInfo curDir = new DirectoryInfo(strPath);//创建目录对象。   
  18. FileInfo[] dirFiles;   
  19. try { dirFiles = curDir.GetFiles(); }   
  20. catch { return; }   
  21. string[] arrSubItem = new string[10];   
  22. //文件的创建时间和访问时间。   
  23. int iCount = 0;   
  24. int iconIndex = 1;//用1,而不用0是要让过0号图标。   
  25. foreach (FileInfo fileInfo in dirFiles)   
  26. string strFileName = fileInfo.Name;   
  27. //如果不是文件pagefile.sys   
  28. if (!strFileName.Equals("pagefile.sys"))   
  29. { arrSubItem[0] = strFileName;   
  30. if (fileInfo.Extension.Trim() == "")   
  31. arrSubItem[1] = "未知类型";   
  32. else  
  33. arrSubItem[1] = fileInfo.Extension.ToString();   
  34. arrSubItem[2] = fileInfo.Length + "字节";   
  35. arrSubItem[3] = fileInfo.CreationTime.ToString();   
  36. arrSubItem[4] = fileInfo.LastAccessTime.ToString(); 
  37. arrSubItem[5] = fileInfo.Directory.ToString(); }   
  38. else  
  39. { arrSubItem[1] = "未知扩展名";   
  40. arrSubItem[2] = "未知大小";   
  41. arrSubItem[3] = "未知日期";   
  42. arrSubItem[4] = "未知日期";   
  43. arrSubItem[5] = "未知上级文件夹"; }   
  44. //得到每个文件的图标   
  45. string str = fileInfo.FullName;   
  46. try { SetIcon(this.ListViewImageList, str, true); }   
  47. catch (Exception ex)   
  48. { MessageBox.Show(ex.Message, "错误提示", 0, MessageBoxIcon.Error); }   
  49. //插入列表项   
  50. ListViewItem LiItem = new ListViewItem(arrSubItem, iconIndex);   
  51. listView1.Items.Insert(iCount, LiItem);   
  52. iCount++;   
  53. iconIndex++;   
  54. }   
  55. strFilePath = strPath;   
  56. this.Cursor = Cursors.Arrow;   
  57. //以下是向列表框中插入目录,不是文件。获得当前目录下的各个子目录。   
  58. int iItem = 0;   
  59. DirectoryInfo Dir = new DirectoryInfo(strPath);   
  60. string[] arrDirectorySubItem = new string[10];   
  61. foreach (DirectoryInfo di in Dir.GetDirectories())   
  62. { arrDirectorySubItem[0] = di.Name;   
  63. if (di.Extension.Trim() != "")   
  64. arrDirectorySubItem[1] = di.Extension;   
  65. else  
  66. { arrDirectorySubItem[1] = "   
  67. ";   
  68. arrDirectorySubItem[2] = "";   
  69. arrDirectorySubItem[3] = "";   
  70. arrDirectorySubItem[4] = "";   
  71. arrDirectorySubItem[5] = ""; } 
  72. ListViewItem LiItem = new ListViewItem(arrDirectorySubItem, 0);   
  73. listView1.Items.Insert(iItem, LiItem);   
  74. iItem++;   
  75. }   
  76. }    

   

  (4) 在构造自定treeView1_AfterSelect中的“AddDirectories(e.Node);”语句后添加下语句。

   

   

  1. InitList(e.Node);    

   

  三、删除系统自带的四个游戏程序

  (1)自定义函数,用于删除Windows2000的四个系统自带游戏

   

  

   

  1. private void DelSystemFourGames()   
  2. string str="";   
  3. StringBuilder buff1 = new StringBuilder(nChars);   
  4. StringBuilder buff2 = new StringBuilder(nChars);   
  5. GetSystemDirectory(Buff, nChars);   
  6. Buff.Append("\\");   
  7. GetSystemDirectory(buff1, nChars);   
  8. buff1.Append("\\");   
  9. buff2=buff1;   
  10. str="sol.exe"; 
  11. if(File_in_Directory(str, buff1.ToString()))   
  12. { Buff.Append("sol.exe");//纸牌   
  13. buff2.Append("DllCache\\");   
  14. buff2.Append("sol.exe");   
  15. //执行删除文件,删除后的文件不出现在回收站中   
  16. File.Delete(Buff.ToString());   
  17. File.Delete(buff2.ToString());  
  18. Buff.Remove(Buff.Length - 7, 7);   
  19. //还原Buff的字符为system32\目录下,7是“sol.exe”的长度   
  20. buff2.Remove(buff2.Length - 7, 7);//类上,还原为dllcache\目录下   
  21. }   
  22. …… 
  23. //省略了删除“空当接龙”和“扫雷”两个游戏的程序段因其内容同上,只不过改str = "freecell.exe"   
  24. //和str = "winmine.exe",以及Buff.Remove中的数字长度与相应的文件名长度一致。   
  25. // 删除windows XP中的蜘蛛“spider.exe”与上类同   
  26. GetSystemDirectory(Buff, nChars);   
  27. GetSystemDirectory(buff2, nChars);  
  28. buff2.Append("\\");   
  29. Buff.Remove(3, Buff.Length - 3); //反回到“盘符:\”状态   
  30. Buff.Append("Program Files\\WIndows NT\\Pinball");//桌上弹球   
  31. str = "pinball.exe";   
  32. if (File_in_Directory(str, Buff.ToString()))   
  33. { DeleteDir(Buff.ToString());//删除目录   
  34. buff2.Append("DllCache\\");   
  35. buff2.Append("pinball.exe");  
  36. File.Delete(buff2.ToString()); 
  37. }   
  38. }  

   

  (2)在button1_OnClick中调用自定义删除函数

   

  

   

  1. DelSystemFourGames(); 

   

  四、两个自定义函数

  1.判断文件是否在指定的文件夹中

   

  

   

  1. private bool File_in_Directory(string str1, string str2)   
  2. {   
  3. DirectoryInfo curDir = new DirectoryInfo(str2);//创建目录对象。   
  4. FileInfo[] dirFiles;   
  5. try  
  6. { dirFiles = curDir.GetFiles(); }   
  7. catch  
  8. return false; }   
  9. foreach (FileInfo fileInfo in dirFiles)   
  10. if (fileInfo.Name == str1) return true; }   
  11. return false;   
  12. }    

   

  2.删除目录及目录下所有文件与子目录

   

  

   

  1. public static void DeleteDir(string Path)   
  2. try  
  3. // 检查路径名是否以分割字符结束,如果不是则添加”\”分隔符   
  4. if (Path[Path.Length - 1] != Path.DirectorySeparatorChar)   
  5. Path += Path.DirectorySeparatorChar;   
  6. string[] fileList = Directory.GetFileSystemEntries(Path);   
  7. // 遍历所有的文件和目录   
  8. foreach (string file in fileList)   
  9. {   
  10. // 先将文件当作目录处理如果存在这个目录就递归Delete该目录下面的文件   
  11. if (Directory.Exists(file))   
  12. {   
  13. DeleteDir(Path + Path.GetFileName(file));   
  14. }   
  15. else // 否则直接Delete文件   
  16. //改变文件的只读属性   
  17. FileInfo fi = new FileInfo(file);   
  18. if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)   
  19. fi.Attributes = FileAttributes.Normal;   
  20. File.Delete(Path + Path.GetFileName(file)); //删除文件   
  21. }   
  22. }   
  23. System.IO.Directory.Delete(Path, true); //删除文件夹   
  24. }   
  25. catch (Exception e)   
  26. { MessageBox.Show(e.ToString()); }   
  27. }  

   

  附言:本文程序采用的是Visual Studio 2005 C#编写,所述代码均已在Windows 2000 pro/server中运行通过。

  本文通过C#编程实现了删除Windows 2000系统自带游戏这个目标,并将微软为考虑自身安全的dllcache目录及其中的文件显示出来,希望能够对要了解这方面的相关人员有所帮助。

在线留言

我要留言