mis导入器的加强版——vdproj文件资源浏览器

  上次做的那个导入器不够强大,限制还不小,用起来不方便。于是就再做一个这样的工具。代码基本上不同了,思想还是差不多,但功能肯定比之前的强大。经过了这次编写工具,对vdporj文件的了解又深一层了。

在vs的文件系统编辑器使用过程中,发现有两个不方便:第一是删除文件夹不方便,如果一个文件夹不是空的话,是删不成功的;第二是添加文件夹时,只能添加该文件夹的文件,如果指定的文件夹含有子文件夹,那些子文件夹就要手动一个个去添加,不会一同添加进去。

  针对第二个问题,我就写出了之前的那个导入器,针对第一个问题,我就写了这个浏览器。这回就先看一下界面

mis导入器的加强版——vdproj文件资源浏览器

 mis导入器的加强版——vdproj文件资源浏览器

功能大致有一下几个

         同步文件夹:把“应用程序文件夹”里的某个文件夹与磁盘上的某个文件夹同步,使得与磁盘上的文件夹有相同的文件和子文件夹。

         添加文件夹:把磁盘上某个文件夹的添加进来,包括了文件夹的文件和它的所有子文件夹的文件。

         删除文件夹:把该文件夹的内容(包括文件和文件夹)删除。

         添加文件:把一个或多个文件添加到文件夹中。

         删除文件:把一个或多个文件删除。

不过像vs里面的复制,剪切,粘贴,拖拽这些功能就没有实现了。

 

介绍了工具的功能到介绍工具的实现了

 

下面则是所用到的类和它的体系结构图

mis导入器的加强版——vdproj文件资源浏览器

这里的类大致上与之前的差不多,GUIDCreater是生成GUID值的;SpecialCharacter是记录处理一些特殊字符的;RegexCollection是存放着一些公共的正则表达式。GUIDCreater和SpecialCharacter的源码跟上次的一样。SetupFileInfo,SetupHierarchy,SetupDirectoryInfo这三个类又要唠叨一下。

带Setup开头的几个类,就是vdproj文件里面几个数据项的类,这次就新增了一个SetupHierachy类。这些类存放着各种对象的信息,以及一些自身的方法。

由平时对文件系统的理解和对vdproj文件的分析,得出这三个类的关系是这样的:

  • SetupDirectoryInfo对象包含有若干个SetupDirectoryInfo对象和若干个SetupFileInfo对象;
  • 一个SetupFileInfo对象只对应这一个SetupHierarchy对象;

因此SetupDirectoryInfo中应该要有一个存放SetupDirectoryInfo对象的集合和一个SetupFileInfo对象的集合;SetupFileInfo中有一个字段存放与之对应的SetupHierarchy对象。

这三个类的字段与属性定义如下

SetupHierarchy类的

 1         public string MsmKey { get; set; }

 2 

 3         private string _ownerKey;

 4         public string  OwnerKey 

 5         {

 6             get 

 7             {

 8                 if (string.IsNullOrEmpty(_ownerKey))

 9                     _ownerKey = "_UNDEFINED";

10                 return _ownerKey;

11             }

12             set

13             {

14                 _ownerKey = value;

15             }

16         }

17 

18         private string _msnSig;

19         public string MsmSig

20         {

21             get

22             {

23                 if (string.IsNullOrEmpty(_msnSig))

24                     _msnSig = "_UNDEFINED";

25                 return _msnSig;

26             }

27             set

28             {

29                 _msnSig = value;

30             } 

31         }

SetupFileInfo类的

1         public string GUID_1

2         { get { return "1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE"; } }

3         public string SourcePath { get; set; }

4         public string TargetName { get; set; }

5         public string Folder { get; set; }

6         public string GUID_2 { get; set; }

7         public SetupHierarchy Hierachy { get; set; }

SetupDirectoryInfo类的

1  public static string GUID_1

2         { get { return "9EF0B969-E518-4E46-987F-47570745A589"; } }

3         public string GUID_2 { get; set; }

4         public string Property { get; set; }

5         public string Name { get; set; }

6         public List<SetupDirectoryInfo> Folders { get; set; }

7         public List<SetupFileInfo> Files { get; set; }

对这三个类的其他成员,就是把vdproj文件提取出来构造对象的方法还有把对象转换成字符串的方法。

         整个工具的核心就是一个ExplorerCore类,它处理着整个各种业务,包括对vdproj的分析,增删改文件夹;它还管理所有文件夹,文件对象;

         对于管理文件夹和文件,ExplorerCore这个核心类使用了6个集合和2个对象,分别是

  • DirDictionary(文件夹字典集):利用文件夹对象SetupDirecotryInfo中GUID2值作为键值的字典集,目的在于能通过GUID值方便获取到文件夹对象
  • DirFile(文件字典集):利用文件对象SetupFileInfo中GUID2值作为键值的字典集,目的在于能通过GUID值方便获取到文件对象
  • FileList(文件列表):文件对象SetupFileInfo的列表,在生成所有文件的字符串时遍历使用。
  • OrgHierachyList(无对应文件的Hierachy列表):存放着未与文件对应的Hierachy对象,刚从vdproj文件分析出来的Hierachy对象都先存放在此集合。
  • OwnerHierachyList(有对应文件的Hierachy列表):存放着已于文件对应的Hierachy对象。
  • GarbageGUID(已经废弃的GUID列表):存放着已被删除的文件或文件夹的GUID值
  • OtherFiles(一些解析不成功的文件信息):以字符串的形式存放着解析不出来的文件信息
  • RootFolder(根文件夹对象):整个文件系统树形结构的根,也就是“应用程序文件夹”的对象。

  经过多次的实践得出,这个文件或文件夹的唯一标识码GUID值在vdproj文件中有很大的作用,文件和文件夹通过它进行关联,程序的快捷方式通过它跟指定的文件、文件夹进行关联。因此在删除一个文件或文件夹之后,一定要被删除的对象的GUID值记录起来。等到保存成vdproj的之后统一把文件存在的废弃GUID码删除替换掉。否则保存之后如果vdproj还存在着废弃的GUID码,vs会打不开那个vdproj文件的。

  ExplorerCore这个核心类的方法就不逐一介绍了,到本文最后就会把整个类的代码粘贴出来。工具写出来了,毛病还是有的,不过至少满足现在的使用需求,能让我打包方便点儿,对类的分析好像还很混乱,有些地方为啥要这样做我也说不清楚(就比如那个SetupHierarchy的对象啥要分开成与文件关联和未与文件关联两个列表存放),还有一个弊病就是产生的字符串太多了,对GC不怎么友好。还有本文的思路很不清晰,呵呵,莫怪。

mis导入器的加强版——vdproj文件资源浏览器
  1     class ExplorerCore

  2     {

  3         private string FileFullName { get; set; }

  4         private SetupDirectoryInfo RootFolder { get; set; }

  5 

  6         private string _otherFiles;

  7         private string OtherFiles 

  8         {

  9             get

 10             {

 11                 if (string.IsNullOrEmpty(_otherFiles))

 12                 {

 13                     string vdpproj = File.ReadAllText(FileFullName, Encoding.UTF8);

 14                     _otherFiles = Regex.Match(vdpproj, RegexCollection.RegFilesInner).Value;

 15                     _otherFiles = Regex.Replace(_otherFiles, RegexCollection.RegFileString, "");

 16                     _otherFiles = Regex.Replace(_otherFiles, @"\s+\r\n", "");

 17                     if (string.IsNullOrEmpty(_otherFiles))

 18                         _otherFiles = "\r\n";

 19                 }

 20                 return "\r\n"+_otherFiles+"\r\n";

 21             }

 22         }

 23 

 24         private Dictionary<string, SetupDirectoryInfo> _dirDictionary;

 25         private Dictionary<string, SetupDirectoryInfo> DirDictionary

 26         {

 27             get

 28             {

 29                 if (_dirDictionary == null)

 30                     _dirDictionary = new Dictionary<string, SetupDirectoryInfo>();

 31                 return _dirDictionary;

 32             }

 33         }

 34 

 35 

 36         private Dictionary<string, SetupFileInfo> _dirFile;

 37         private Dictionary<string, SetupFileInfo> DirFile

 38         {

 39             get

 40             {

 41                 if (_dirFile == null)

 42                     _dirFile =new Dictionary<string, SetupFileInfo>();

 43                 return _dirFile;

 44             }

 45         }

 46 

 47         private List<SetupFileInfo> _fileList;

 48         private List<SetupFileInfo> FileList

 49         {

 50             get

 51             {

 52                 if (_fileList == null)

 53                     _fileList = new List<SetupFileInfo>();

 54                 return _fileList;

 55             }

 56         }

 57 

 58         private List<SetupHierarchy> _orgHierachyList;

 59         private List<SetupHierarchy> OrgHierachyList

 60         {

 61             get

 62             {

 63                 if (_orgHierachyList == null)

 64                     _orgHierachyList = new List<SetupHierarchy>();

 65                 return _orgHierachyList;

 66             }

 67         }

 68 

 69         private List<SetupHierarchy> _ownerHierachyList;

 70         private List<SetupHierarchy> OwnerHierachyList

 71         {

 72             get

 73             {

 74                 if (_ownerHierachyList == null)

 75                     _ownerHierachyList = new List<SetupHierarchy>();

 76                 return _ownerHierachyList;

 77             }

 78         }

 79 

 80         private List<string> _garbageGUID;

 81         private List<string> GarbageGUID

 82         {

 83             get

 84             {

 85                 if (_garbageGUID == null)

 86                     _garbageGUID = new List<string>();

 87                 return _garbageGUID;

 88             }

 89         }

 90 

 91         private void GCGUID(string guid)

 92         {

 93             if (GarbageGUID.Contains(guid)) return;

 94             GarbageGUID.Add(guid);

 95         }

 96 

 97         /// <summary>

 98         /// 增加文件夹到集合中

 99         /// </summary>

100         /// <param name="info"></param>

101         private void AddDirectory(SetupDirectoryInfo info)

102         {

103             if (!DirDictionary.ContainsKey(info.GUID_2))

104                 DirDictionary.Add(info.GUID_2, info);

105         }

106 

107         /// <summary>

108         /// 增加文件到其所属文件夹中

109         /// </summary>

110         /// <param name="info"></param>

111         private void AddFileToDircotory(SetupFileInfo info)

112         {

113             if (DirDictionary.ContainsKey(info.Folder) &&

114                 !DirDictionary[info.Folder].Files.Contains(info))

115                 DirDictionary[info.Folder].Files.Add(info);

116         }

117 

118         /// <summary>

119         /// 增加文件到文件列表中

120         /// </summary>

121         /// <param name="info"></param>

122         private void AddFile(SetupFileInfo info)

123         {

124             FileList.Add(info);

125             DirFile.Add(info.GUID_2, info);

126         }

127 

128         /// <summary>

129         /// 把文件夹 文件 Hierachy组合在一起

130         /// </summary>

131         private void CombineObjects()

132         {

133             foreach (SetupFileInfo item in FileList)

134                 AddFileToDircotory(item);

135 

136             for (int i = 0; i < _orgHierachyList.Count; i++)

137             {

138                 if (DirFile.ContainsKey(OrgHierachyList[i].MsmKey))

139                 {

140                     DirFile[OrgHierachyList[i].MsmKey].Hierachy = OrgHierachyList[i];

141                     OwnerHierachyList.Add(OrgHierachyList[i]);

142                     OrgHierachyList.RemoveAt(i);

143                     i--;

144                 }

145             }

146         }

147 

148         /// <summary>

149         /// 初始化读入文档内容,分析并构建起树

150         /// </summary>

151         /// <param name="fileName"></param>

152         /// <returns></returns>

153         public SetupDirectoryInfo InitExplorer(string fileName)

154         {

155             FileFullName = fileName;

156             string vdprojContent = File.ReadAllText(fileName, Encoding.UTF8);

157 

158             string strFolder = Regex.Match(vdprojContent, RegexCollection.RegFoldersInner).Value;

159             SetupDirectoryInfo root = new SetupDirectoryInfo()

160             {

161                 GUID_2 = Regex.Match(vdprojContent, RegexCollection.RegAppFolderGuid2).Value,

162                 Name = "应用程序文件夹",

163                 Files = new List<SetupFileInfo>(),

164                 Folders = new List<SetupDirectoryInfo>()

165             };

166             RootFolder = root;

167             AddDirectory(root);

168             SetupDirectoryInfo.CreateSetupDirectoryInfo(strFolder, root,this.DirDictionary);

169 

170             string strFiles = Regex.Match(vdprojContent, RegexCollection.RegFilesInner).Value;

171             MatchCollection fileMatch = Regex.Matches(strFiles, RegexCollection.RegFileString);

172             foreach (Match item in fileMatch)

173                 AddFile(SetupFileInfo.CreateSetupFileInfo(item.Value));

174 

175             string strHierachy = Regex.Match(vdprojContent, RegexCollection.RegHierachyInner).Value;

176             MatchCollection hierachyMatch = Regex.Matches(strHierachy, RegexCollection.RegHierarchy);

177             foreach (Match item in hierachyMatch)

178                 OrgHierachyList.Add(SetupHierarchy.CreateHierarchy(item.Value));

179 

180             CombineObjects();

181             return root;

182         }

183 

184         /// <summary>

185         /// 可视化界面 删除文件

186         /// </summary>

187         /// <param name="file"></param>

188         public void DeleteFile(SetupFileInfo file)

189         {

190             FileList.Remove(file);

191             DirFile.Remove(file.GUID_2);

192             OwnerHierachyList.Remove(file.Hierachy);

193             DirDictionary[file.Folder].Files.Remove(file);

194             GCGUID(file.GUID_2);

195         }

196 

197         /// <summary>

198         /// 可视化界面 增加文件

199         /// </summary>

200         /// <param name="dir"></param>

201         /// <param name="fileInfo"></param>

202         public void AddFile(SetupDirectoryInfo dir, FileInfo fileInfo)

203         {

204             SetupFileInfo file = new SetupFileInfo();

205 

206             file.GUID_2 = GUIDCreater.CreateGUID2();

207             file.SourcePath = fileInfo.FullName.Replace("\\", "\\\\");

208             file.TargetName = fileInfo.Name;

209             file.Folder = dir.GUID_2;

210             file.Hierachy = new SetupHierarchy(file);

211 

212             AddFile(file);

213             AddFileToDircotory(file);

214             OwnerHierachyList.Add(file.Hierachy);

215         }

216 

217         /// <summary>

218         /// 可视化界面 删除文件夹

219         /// </summary>

220         /// <param name="dir"></param>

221         public void DeleteDircetory(SetupDirectoryInfo dir,SetupDirectoryInfo parent)

222         {

223             //foreach (SetupFileInfo file in dir.Files)

224             while (dir.Files.Count>0)

225                 DeleteFile(dir.Files[0]);

226             //foreach (SetupDirectoryInfo subDir in dir.Folders)

227             while (dir.Folders.Count>0)

228                 DeleteDircetory(dir.Folders[0],dir);

229             parent.Folders.Remove(dir);

230             DirDictionary.Remove(dir.GUID_2);

231             GCGUID(dir.GUID_2);

232         }

233 

234         /// <summary>

235         /// 可视化界面 增加文件夹

236         /// </summary>

237         /// <param name="dirInfo"></param>

238         /// <param name="dir"></param>

239         public void AddDirectory(SetupDirectoryInfo dirInfo, DirectoryInfo dir)

240         {

241 

242             SetupDirectoryInfo currDir = new SetupDirectoryInfo();

243             currDir.Name = dir.Name;

244             currDir.GUID_2 = GUIDCreater.CreateGUID2();

245             currDir.Property = GUIDCreater.CreateGUID2();

246             currDir.Files = new List<SetupFileInfo>();

247             currDir.Folders = new List<SetupDirectoryInfo>();

248 

249             DirectoryInfo[] dirs = dir.GetDirectories();

250             List<SetupDirectoryInfo> folderList = new List<SetupDirectoryInfo>(dirs.Length);

251             foreach (DirectoryInfo item in dirs)

252                 AddDirectory(currDir, item);

253             AddDirectory(currDir);

254             dirInfo.Folders.Add(currDir);

255 

256             FileInfo[] files = dir.GetFiles();

257             List<SetupFileInfo> fileList = new List<SetupFileInfo>(files.Length);

258             foreach (FileInfo file in files)

259                 AddFile(currDir, file);

260         }

261 

262         /// <summary>

263         /// 可视化界面 同步文件夹

264         /// </summary>

265         /// <param name="dirInfo"></param>

266         /// <param name="dir"></param>

267         public void SynDirectory(SetupDirectoryInfo dirInfo, DirectoryInfo dir)

268         {

269             DirectoryInfo[] dirArry = dir.GetDirectories();

270             List<SetupDirectoryInfo> newDirList = new List<SetupDirectoryInfo>(dirArry.Length);

271             SetupDirectoryInfo newDir = null;

272             foreach (DirectoryInfo item in dirArry)

273             {

274                 newDir = dirInfo.ExistSubDirectory(item.Name);

275                 if (newDir != null)

276                 {

277                     newDirList.Add(newDir);

278                     dirInfo.Folders.Remove(newDir);

279                 }

280                 else

281                 {

282                     newDir = new SetupDirectoryInfo();

283                     newDir.Name = item.Name;

284                     newDir.GUID_2 = GUIDCreater.CreateGUID2();

285                     newDir.Property = GUIDCreater.CreateGUID2();

286                     newDir.Files = new List<SetupFileInfo>();

287                     newDir.Folders = new List<SetupDirectoryInfo>();

288 

289                     AddDirectory(newDir);

290                     newDirList.Add(newDir);

291                 }

292                 SynDirectory(newDir, item);

293             }

294             while (dirInfo.Folders.Count > 0)

295                 DeleteDircetory(dirInfo.Folders[0], dirInfo);

296             dirInfo.Folders = newDirList;

297 

298             FileInfo[] fileArry = dir.GetFiles();

299             List<SetupFileInfo> newFileList = new List<SetupFileInfo>(fileArry.Length);

300             SetupFileInfo newFile = null;

301             foreach (FileInfo item in fileArry)

302             {

303                 newFile = dirInfo.ExistFile(item.Name);

304                 if (newFile != null)

305                 {

306                     newFile.SourcePath = item.FullName.Replace("\\", "\\\\");

307                     newFileList.Add(newFile);

308                     dirInfo.Files.Remove(newFile);

309                 }

310                 else

311                 {

312                     SetupFileInfo file = new SetupFileInfo();

313 

314                     file.GUID_2 = GUIDCreater.CreateGUID2();

315                     file.SourcePath = item.FullName.Replace("\\", "\\\\");

316                     file.TargetName = item.Name;

317                     file.Folder = dirInfo.GUID_2;

318                     file.Hierachy = new SetupHierarchy(file);

319 

320                     AddFile(file);

321                     //AddFileToDircotory(file);

322                     newFileList.Add(file);

323                     OwnerHierachyList.Add(file.Hierachy);

324                 }

325                     //AddFile(dirInfo, item);

326             }

327             while (dirInfo.Files.Count > 0)

328                 DeleteFile(dirInfo.Files[0]);

329             dirInfo.Files = newFileList;

330 

331         }

332 

333         public void SaveFile()

334         {

335             Initial();

336             StringBuilder sbFile = new StringBuilder();

337             foreach (SetupFileInfo item in FileList)

338                 sbFile.Append(item.CreateFileItemInfo());

339             sbFile.Append(OtherFiles);

340 

341             StringBuilder sbHierachy=new StringBuilder();

342             foreach (SetupHierarchy item in OwnerHierachyList)

343                 sbHierachy.Append(item.ToString());

344             foreach (SetupHierarchy item in OrgHierachyList)

345                 sbHierachy.Append(item.ToString());

346 

347             //string strFolders = RootFolder.CreateFoldersString();

348             StringBuilder sbFolder = new StringBuilder();

349             foreach (SetupDirectoryInfo item in RootFolder.Folders)

350                 sbFolder.Append(item.CreateFoldersString());

351 

352             string vdprojContent = SpecialCharacter.ChangeSpecialCharacter(File.ReadAllText(FileFullName, Encoding.UTF8));

353             File.Copy(FileFullName, FileFullName + ".bak", true);

354 

355             vdprojContent =SpecialCharacter.RecoverSpecialCharacter( OverWriteContent(vdprojContent,

356                SpecialCharacter.ChangeSpecialCharacter( sbHierachy.ToString()),

357                 SpecialCharacter.ChangeSpecialCharacter( sbFile.ToString()),

358                SpecialCharacter.ChangeSpecialCharacter( sbFolder.ToString())

359             ));

360             vdprojContent= SafeCheckGUID(vdprojContent);

361             File.WriteAllText(FileFullName, vdprojContent, Encoding.UTF8);

362             Finish();

363         }

364 

365 

366         private string SafeCheckGUID(string vdprojContent)

367         {

368             if (_garbageGUID == null) return vdprojContent;

369             foreach (string guidItem in GarbageGUID)

370                vdprojContent= vdprojContent.Replace(guidItem, "");

371             return vdprojContent;

372         }

373 

374         private string OverWriteContent(string vdprojContent, string strHierarchy, string strFiles, string strFolders)

375         {

376             vdprojContent = Regex.Replace(vdprojContent, RegexCollection.RegFilesInner, strFiles);

377             vdprojContent = Regex.Replace(vdprojContent, RegexCollection.RegFoldersInner, strFolders);

378             vdprojContent = Regex.Replace(vdprojContent, RegexCollection.RegHierachyInner, strHierarchy);

379 

380             return vdprojContent;

381         }

382 

383         private void Initial()

384         {

385             SpecialCharacter.AddCharacter("$");

386         }

387 

388         private void Finish()

389         {

390             SpecialCharacter.ClearRecord();

391             GC.Collect();

392         }

393     }
ExplorerCore核心类

 

你可能感兴趣的:(浏览器)