批量修改快捷方式目标 C#
因为某些原因硬盘分区的卷标都更改了,导致之前的大量快捷方失效。重新生成快捷方式又嬚麻烦,就写了个批量修改快捷方式的小程序。
程序如下图:
很多软件之前都是在D:\Program Files (x86)中,现在只用改到E盘就可以了。
界面初始化
/// <summary> /// 文件类型,格式示例:*.lnk /// </summary> public const string fileType = "*.lnk"; public FrmMain() { InitializeComponent(); CmbLstStyle.SelectedIndex = 0; chFileName.Width = (int)(LsvShortcut.Width * 0.3); chFileLink.Width = (int)(LsvShortcut.Width * 0.5); chFileDate.Width = LsvShortcut.Width - chFileName.Width - chFileLink.Width - 30; }
更新指定的路径下的目录及文件信息到ListView
1 /// <summary> 2 /// 更新指定的路径下的目录及文件信息到ListView 3 /// </summary> 4 /// <param name="path">路径</param> 5 private void UpdateLsvByPath(string path) 6 { 7 if (System.IO.Directory.Exists(path)) 8 {//获取选择的目录路径 9 DirectoryInfo dirRoot = new DirectoryInfo(path); 10 11 TxtPath.Text = path; 12 13 for (int i = 1; i < ImgList.Images.Count - 1; i++) 14 {//清空图标列表 15 ImgList.Images.RemoveAt(i); 16 } 17 18 //清空ListView目录树 19 LsvShortcut.Items.Clear(); 20 LsvShortcut.BeginUpdate(); 21 22 ListViewItem lvi; 23 ListViewItem.ListViewSubItem lvsi; 24 25 #region 返回上级 26 if (dirRoot.Parent != null) 27 { 28 lvi = new ListViewItem(); 29 lvi.Text = ".."; 30 lvi.ImageIndex = 0; 31 lvi.Tag = dirRoot.Parent.FullName; 32 LsvShortcut.Items.Add(lvi); 33 } 34 #endregion 35 36 try 37 { 38 #region 获取指定目录下所有目录 39 DirectoryInfo[] dirs = dirRoot.GetDirectories(); 40 foreach (var dir in dirs) 41 { 42 //在ListView上产生一个第1列(名称) 43 lvi = new ListViewItem(); 44 lvi.Text = dir.Name; 45 lvi.Tag = dir.FullName; 46 lvi.ImageIndex = 0; 47 //在ListView中产生一个目录的第2列(符合的文件数量) 48 lvsi = new ListViewItem.ListViewSubItem(); 49 lvsi.Text = dir.GetFiles(fileType).Length + "个符合的文件"; 50 lvi.SubItems.Add(lvsi); 51 //在ListView中产生一个目录的第3列(最后访问时间) 52 lvsi = new ListViewItem.ListViewSubItem(); 53 lvsi.Text = dir.LastAccessTime.ToShortDateString(); 54 lvi.SubItems.Add(lvsi); 55 56 //将整个Item添加到ListView上 57 LsvShortcut.Items.Add(lvi); 58 } 59 #endregion 60 61 #region 获取指定目录下所有文件 62 FileInfo[] filesRoot = dirRoot.GetFiles(fileType); 63 foreach (var fileInfo in filesRoot) 64 { 65 #region 在ListView上产生一个文件的第一列(名称) 66 lvi = new ListViewItem(); 67 lvi.Text = fileInfo.Name; 68 lvi.Tag = fileInfo.FullName; 69 // lvi.ImageIndex = 1; 70 71 ImgList.Images.Add(IconClass.GetFileIcon(fileInfo.FullName)); 72 lvi.ImageIndex = ImgList.Images.Count - 1; 73 74 #endregion 75 76 #region 在ListView上产生一个文件 第2列(快捷方式指向或者文件大小) 77 string text = string.Empty;//要显示的内容 78 79 if (fileType.Equals("*.lnk")) 80 {//表示当前需要的是快捷方式。这一行显示快捷方式的指向 81 WshShell shell = new WshShell(); 82 IWshShortcut iwsc = (IWshShortcut)shell.CreateShortcut(fileInfo.FullName); 83 text = iwsc.TargetPath; 84 lvi.ToolTipText = text; 85 } 86 else 87 {//非快捷方式操作,获取该文件大小 88 text = fileInfo.Length.ToString(); 89 } 90 91 lvsi = new ListViewItem.ListViewSubItem(); 92 lvsi.Text = text; 93 lvi.SubItems.Add(lvsi); 94 #endregion 95 96 #region 在ListView上产生一个文件的第3列(最后修改时间) 97 lvsi = new ListViewItem.ListViewSubItem(); 98 lvsi.Text = fileInfo.LastAccessTime.ToShortDateString(); 99 lvi.SubItems.Add(lvsi); 100 #endregion 101 102 //将整个ListViewItem添加到ListView上 103 LsvShortcut.Items.Add(lvi); 104 } 105 106 107 #endregion 108 109 } 110 catch (System.Exception ex) 111 { 112 MessageBox.Show(ex.Message); 113 if (dirRoot.Parent != null) 114 { 115 UpdateLsvByPath(dirRoot.Parent.FullName); 116 } 117 } 118 finally 119 { 120 //结束操作ListView 121 LsvShortcut.EndUpdate(); 122 } 123 } 124 }
打开选择的目录
1 //ListView双击某项时的事件 2 private void LsvShortcut_ItemActivate(object sender, EventArgs e) 3 { 4 ListView lsv = (ListView)sender; 5 string fileName = lsv.SelectedItems[0].Tag.ToString(); 6 7 //打开当前选择的目录 8 if (lsv.SelectedItems[0].ImageIndex == 0) 9 { 10 UpdateLsvByPath(fileName); 11 } 12 }
获取ListView列表中的所有符合条件的链接集合
1 /// <summary> 2 /// 获取ListView列表中的所有符合条件的链接集合 3 /// </summary> 4 /// <param name="strSearch">要匹配的字符串</param> 5 /// <returns>Dictionary[int, string]</returns> 6 private Dictionary<int, string> GetDicLinks(string strSearch) 7 { 8 Dictionary<int, string> dic = new Dictionary<int, string>(); 9 for (int i = 1; i < LsvShortcut.Items.Count; i++) 10 { 11 string str = LsvShortcut.Items[i].SubItems[1].Text; 12 if (str.Contains(strSearch)) 13 { 14 dic.Add(i, str); 15 } 16 } 17 return dic; 18 }
替换所有匹配的快捷方式
1 //替换所有 2 private void BtnReplaceAll_Click(object sender, EventArgs e) 3 { 4 string strOld = TxtOld.Text; 5 string strNew = TxtNew.Text; 6 if (string.IsNullOrEmpty(strOld)) return; 7 8 Dictionary<int, string> dic = GetDicLinks(strOld); 9 10 foreach (var item in dic) 11 { 12 int index = item.Key; 13 string value = item.Value; 14 ListViewItem lvi = LsvShortcut.Items[index]; 15 string fullName = lvi.Tag.ToString(); 16 //更改快捷方式的指向 17 WshShell shell = new WshShell(); 18 IWshShortcut iwsc = (IWshShortcut)shell.CreateShortcut(fullName); 19 iwsc.TargetPath = value.Replace(strOld, strNew); 20 iwsc.Save(); 21 } 22 23 if (dic.Count > 0) 24 {//刷新显示 25 UpdateLsvByPath(Directory.GetParent(LsvShortcut.Items[1].Tag.ToString()).FullName); 26 } 27 }
其中获取快捷方式或文件图标的方法使用的是zgke的方法:http://blog.csdn.net/zgke/article/details/3873030
代码如下:
获取文件或文件夹图标相关的类
1 using System; 2 using System.Drawing; 3 using System.Runtime.InteropServices; 4 5 namespace 批量修改快捷方式 6 { 7 /// <summary> 8 /// 获取文件或文件夹图标相关的类 9 /// </summary> 10 class IconClass 11 { 12 [StructLayout(LayoutKind.Sequential)] 13 public struct SHFILEINFO 14 { 15 public IntPtr hIcon; 16 public IntPtr iIcon; 17 public uint dwAttributes; 18 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 19 public string szDisplayName; 20 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 21 public string szTypeName; 22 } 23 24 /// <summary> 25 /// 返回系统设置的图标 26 /// </summary> 27 /// <param name="pszPath">文件路径 如果为"" 返回文件夹的</param> 28 /// <param name="dwFileAttributes">0</param> 29 /// <param name="psfi">结构体</param> 30 /// <param name="cbSizeFileInfo">结构体大小</param> 31 /// <param name="uFlags">枚举类型</param> 32 /// <returns>-1失败</returns> 33 [DllImport("shell32.dll")] 34 public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); 35 36 public enum SHGFI 37 { 38 SHGFI_ICON = 0x100, 39 SHGFI_LARGEICON = 0x0, 40 SHGFI_USEFILEATTRIBUTES = 0x10 41 } 42 43 44 /// <summary> 45 /// 获取文件图标 zgke@sina.com qq:116149 46 /// </summary> 47 /// <param name="p_Path">文件全路径</param> 48 /// <returns>图标</returns> 49 public static Icon GetFileIcon(string p_Path) 50 { 51 SHFILEINFO _SHFILEINFO = new SHFILEINFO(); 52 IntPtr _IconIntPtr = SHGetFileInfo(p_Path, 0, ref _SHFILEINFO, (uint)Marshal.SizeOf(_SHFILEINFO), (uint)(SHGFI.SHGFI_ICON | SHGFI.SHGFI_LARGEICON | SHGFI.SHGFI_USEFILEATTRIBUTES)); 53 if (_IconIntPtr.Equals(IntPtr.Zero)) return null; 54 Icon _Icon = System.Drawing.Icon.FromHandle(_SHFILEINFO.hIcon); 55 return _Icon; 56 } 57 /// <summary> 58 /// 获取文件夹图标 zgke@sina.com qq:116149 59 /// </summary> 60 /// <returns>图标</returns> 61 public static Icon GetDirectoryIcon() 62 { 63 SHFILEINFO _SHFILEINFO = new SHFILEINFO(); 64 IntPtr _IconIntPtr = SHGetFileInfo(@"", 0, ref _SHFILEINFO, (uint)Marshal.SizeOf(_SHFILEINFO), (uint)(SHGFI.SHGFI_ICON | SHGFI.SHGFI_LARGEICON)); 65 if (_IconIntPtr.Equals(IntPtr.Zero)) return null; 66 Icon _Icon = System.Drawing.Icon.FromHandle(_SHFILEINFO.hIcon); 67 return _Icon; 68 } 69 } 70 }