public static IList <KeyValuePair <string, Tuple <string, ModuleType> > > GetFolderModules(string folderPath) { var modulesText = new Dictionary <string, Tuple <string, ModuleType> >(); var extensions = new[] { ".bas", ".cls", ".frm" }; var projIni = new ProjectIni(Path.Combine(folderPath, "Project.INI")); if (File.Exists(Path.Combine(folderPath, "Project.INI.local"))) { projIni.AddFile(Path.Combine(folderPath, "Project.INI.local")); } var projEncoding = Encoding.GetEncoding(projIni.GetInt("General", "CodePage") ?? Encoding.Default.CodePage); foreach (var filePath in Directory.GetFiles(folderPath, "*.*").Where(s => extensions.Any(s.EndsWith)).Select(s => Path.Combine(folderPath, Path.GetFileName(s)))) { var moduleText = File.ReadAllText(filePath, projEncoding).TrimEnd('\r', '\n') + "\r\n"; modulesText[Path.GetFileNameWithoutExtension(filePath)] = Tuple.Create(moduleText, ModuleProcessing.TypeFromText(moduleText)); } return(modulesText.ToList()); }
public void Write(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentException("Path to file cannot be null or empty.", nameof(filePath)); } File.Delete(Path.Combine(FolderPath, "vbaProject.bin")); var cf = new CompoundFile(); var vbaProject = cf.RootStorage; var projIni = new ProjectIni(Path.Combine(FolderPath, "Project.INI")); if (File.Exists(Path.Combine(FolderPath, "Project.INI.local"))) { projIni.AddFile(Path.Combine(FolderPath, "Project.INI.local")); } var projEncoding = Encoding.GetEncoding(projIni.GetInt("General", "CodePage") ?? Encoding.Default.CodePage); if (!projEncoding.Equals(Encoding.Default)) { projIni = new ProjectIni(Path.Combine(FolderPath, "Project.INI"), projEncoding); if (File.Exists(Path.Combine(FolderPath, "Project.INI.local"))) { projIni.AddFile(Path.Combine(FolderPath, "Project.INI.local")); } } var projSysKind = (uint)(projIni.GetInt("General", "SysKind") ?? 1); var projVersion = projIni.GetVersion("General", "Version") ?? new Version(1, 1); var refs = new List <Reference>(); foreach (var refName in projIni.GetReferenceNames()) { var refSubj = $"Reference {refName}"; if (projIni.GetString(refSubj, "LibIdTwiddled") != null) { refs.Add(new ReferenceControl { Cookie = (uint)(projIni.GetInt(refSubj, "Cookie") ?? 0), LibIdExtended = projIni.GetString(refSubj, "LibIdExtended"), LibIdTwiddled = projIni.GetString(refSubj, "LibIdTwiddled"), Name = refName, NameRecordExtended = projIni.GetString(refSubj, "NameRecordExtended"), OriginalLibId = projIni.GetString(refSubj, "OriginalLibId"), OriginalTypeLib = projIni.GetGuid(refSubj, "OriginalTypeLib") ?? Guid.Empty }); } else if (projIni.GetString(refSubj, "LibIdAbsolute") != null) { refs.Add(new ReferenceProject { LibIdAbsolute = projIni.GetString(refSubj, "LibIdAbsolute"), LibIdRelative = projIni.GetString(refSubj, "LibIdRelative"), Name = refName, Version = projIni.GetVersion(refSubj, "Version") }); } else { refs.Add(new ReferenceRegistered { LibId = projIni.GetString(refSubj, "LibId"), Name = refName }); } } var mods = new List <Module>(); var modExts = new[] { ".bas", ".cls", ".frm" }; foreach (var modPath in Directory.GetFiles(FolderPath).Where(s => modExts.Contains(Path.GetExtension(s) ?? "", StringComparer.InvariantCultureIgnoreCase))) { var modName = Path.GetFileNameWithoutExtension(modPath); var modText = File.ReadAllText(modPath, projEncoding); var modType = ModuleProcessing.TypeFromText(modText); projIni.RegisterModule(modName, modType, (uint)(projIni.GetInt("DocTLibVersions", modName) ?? 0)); mods.Add(new Module { DocString = GetAttribute(modText, "VB_Description"), HelpContext = GetAttributeUInt(modText, "VB_HelpID"), Name = modName, StreamName = modName, Type = modType }); } vbaProject.AddStream("PROJECT"); vbaProject.GetStream("PROJECT").SetData(projEncoding.GetBytes(projIni.GetProjectText())); vbaProject.AddStream("PROJECTlk"); vbaProject.GetStream("PROJECTlk").SetData(File.Exists(Path.Combine(FolderPath, "LicenseKeys.bin")) ? File.ReadAllBytes(Path.Combine(FolderPath, "LicenseKeys.bin")) : new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }); var projectWm = new List <byte>(); foreach (var modName in mods.Select(m => m.Name)) { projectWm.AddRange(projEncoding.GetBytes(modName)); projectWm.Add(0x00); projectWm.AddRange(Encoding.Unicode.GetBytes(modName)); projectWm.Add(0x00); projectWm.Add(0x00); } projectWm.AddRange(new byte[] { 0x00, 0x00 }); vbaProject.AddStream("PROJECTwm"); vbaProject.GetStream("PROJECTwm").SetData(projectWm.ToArray()); vbaProject.AddStorage("VBA"); var vbaProjectVba = vbaProject.GetStorage("VBA"); vbaProjectVba.AddStream("_VBA_PROJECT"); vbaProjectVba.GetStream("_VBA_PROJECT").SetData(new byte[] { 0xCC, 0x61, 0xFF, 0xFF, 0x00, 0x00, 0x00 }); var dirUc = new List <byte>(); // uncompressed dir stream dirUc.AddRange(BitConverter.GetBytes((short)0x0001)); dirUc.AddRange(BitConverter.GetBytes(4)); dirUc.AddRange(BitConverter.GetBytes(projSysKind)); dirUc.AddRange(BitConverter.GetBytes((short)0x0002)); dirUc.AddRange(BitConverter.GetBytes(4)); dirUc.AddRange(BitConverter.GetBytes(0x00000409)); // LCID dirUc.AddRange(BitConverter.GetBytes((short)0x0014)); dirUc.AddRange(BitConverter.GetBytes(4)); dirUc.AddRange(BitConverter.GetBytes(0x00000409)); // LCIDINVOKE dirUc.AddRange(BitConverter.GetBytes((short)0x0003)); dirUc.AddRange(BitConverter.GetBytes(2)); dirUc.AddRange(BitConverter.GetBytes((short)projEncoding.CodePage)); var projNameBytes = projEncoding.GetBytes(projIni.GetString("General", "Name") ?? ""); dirUc.AddRange(BitConverter.GetBytes((short)0x0004)); dirUc.AddRange(BitConverter.GetBytes(projNameBytes.Length)); dirUc.AddRange(projNameBytes); var projDocStringBytes = projEncoding.GetBytes(projIni.GetString("General", "Description") ?? ""); var projDocStringUtfBytes = Encoding.Unicode.GetBytes(projIni.GetString("General", "Description") ?? ""); dirUc.AddRange(BitConverter.GetBytes((short)0x0005)); dirUc.AddRange(BitConverter.GetBytes(projDocStringBytes.Length)); dirUc.AddRange(projDocStringBytes); dirUc.AddRange(BitConverter.GetBytes((short)0x0040)); dirUc.AddRange(BitConverter.GetBytes(projDocStringUtfBytes.Length)); dirUc.AddRange(projDocStringUtfBytes); var projHelpFileBytes = projEncoding.GetBytes(projIni.GetString("General", "HelpFile") ?? ""); dirUc.AddRange(BitConverter.GetBytes((short)0x0006)); dirUc.AddRange(BitConverter.GetBytes(projHelpFileBytes.Length)); dirUc.AddRange(projHelpFileBytes); dirUc.AddRange(BitConverter.GetBytes((short)0x003D)); dirUc.AddRange(BitConverter.GetBytes(projHelpFileBytes.Length)); dirUc.AddRange(projHelpFileBytes); dirUc.AddRange(BitConverter.GetBytes((short)0x0007)); dirUc.AddRange(BitConverter.GetBytes(4)); dirUc.AddRange(BitConverter.GetBytes(projIni.GetInt("General", "HelpContextID") ?? 0)); dirUc.AddRange(BitConverter.GetBytes((short)0x0008)); dirUc.AddRange(BitConverter.GetBytes(4)); dirUc.AddRange(BitConverter.GetBytes(0)); // LIBFLAGS dirUc.AddRange(BitConverter.GetBytes((short)0x0009)); dirUc.AddRange(BitConverter.GetBytes(4)); dirUc.AddRange(BitConverter.GetBytes(projVersion.Major)); dirUc.AddRange(BitConverter.GetBytes((short)projVersion.Minor)); var projConstantsBytes = projEncoding.GetBytes(projIni.GetConstantsString()); var projConstantsUtfBytes = Encoding.Unicode.GetBytes(projIni.GetConstantsString()); dirUc.AddRange(BitConverter.GetBytes((short)0x000C)); dirUc.AddRange(BitConverter.GetBytes(projConstantsBytes.Length)); dirUc.AddRange(projConstantsBytes); dirUc.AddRange(BitConverter.GetBytes((short)0x003C)); dirUc.AddRange(BitConverter.GetBytes(projConstantsUtfBytes.Length)); dirUc.AddRange(projConstantsUtfBytes); foreach (var rfc in refs) { dirUc.AddRange(rfc.GetBytes(projEncoding)); } dirUc.AddRange(BitConverter.GetBytes((short)0x000F)); dirUc.AddRange(BitConverter.GetBytes(2)); dirUc.AddRange(BitConverter.GetBytes((short)mods.Count)); dirUc.AddRange(BitConverter.GetBytes((short)0x0013)); dirUc.AddRange(BitConverter.GetBytes(2)); dirUc.AddRange(BitConverter.GetBytes((short)-1)); // PROJECTCOOKIE foreach (var mod in mods) { dirUc.AddRange(mod.GetBytes(projEncoding)); } dirUc.AddRange(BitConverter.GetBytes((short)0x0010)); dirUc.AddRange(BitConverter.GetBytes(0)); // global terminator vbaProjectVba.AddStream("dir"); vbaProjectVba.GetStream("dir").SetData(CompoundDocumentCompression.CompressPart(dirUc.ToArray())); foreach (var mod in mods) { switch (mod.Type) { case ModuleType.Class: case ModuleType.StaticClass: vbaProjectVba.AddStream(mod.StreamName); var fileText = File.ReadAllText(Path.Combine(FolderPath, mod.Name + ModuleProcessing.ExtensionFromType(mod.Type)), projEncoding); vbaProjectVba.GetStream(mod.StreamName).SetData(CompoundDocumentCompression.CompressPart(projEncoding.GetBytes(SeparateClassCode(fileText)))); break; case ModuleType.Form: string vbFrame; vbaProjectVba.AddStream(mod.StreamName); vbaProjectVba.GetStream(mod.StreamName).SetData(CompoundDocumentCompression.CompressPart( projEncoding.GetBytes(SeparateVbFrame(File.ReadAllText(Path.Combine(FolderPath, mod.Name + ".frm"), projEncoding), out vbFrame)))); vbaProject.AddStorage(mod.StreamName); var frmStorage = vbaProject.GetStorage(mod.StreamName); frmStorage.AddStream("\x03VBFrame"); frmStorage.GetStream("\x03VBFrame").SetData(projEncoding.GetBytes(vbFrame)); var b = File.ReadAllBytes(Path.Combine(FolderPath, mod.Name + ".frx")); using (var ms = new MemoryStream(b, 24, b.Length - 24)) { var frx = new CompoundFile(ms); CopyCfStreamsExcept(frx.RootStorage, frmStorage, "\x03VBFrame"); } break; default: vbaProjectVba.AddStream(mod.StreamName); vbaProjectVba.GetStream(mod.StreamName).SetData(CompoundDocumentCompression.CompressPart( File.ReadAllBytes(Path.Combine(FolderPath, mod.Name + ModuleProcessing.ExtensionFromType(mod.Type))))); break; } } cf.Save(Path.Combine(FolderPath, "vbaProject.bin")); if (Path.GetFileName(filePath).Equals("vbaProject.bin", StringComparison.InvariantCultureIgnoreCase)) { File.Copy(Path.Combine(FolderPath, "vbaProject.bin"), filePath, true); } else { FileStream fs = null; try { fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite); var sig = new byte[4]; fs.Read(sig, 0, 4); fs.Seek(0, SeekOrigin.Begin); if (sig.SequenceEqual(new byte[] { 0x50, 0x4b, 0x03, 0x04 })) { var zipFile = new ZipFile(fs); var zipEntry = zipFile.Cast <ZipEntry>().FirstOrDefault(e => e.Name.EndsWith("vbaProject.bin", StringComparison.InvariantCultureIgnoreCase)); if (zipEntry == null) { throw new ApplicationException("Cannot find 'vbaProject.bin' in ZIP archive."); } zipFile.BeginUpdate(); zipFile.Add(Path.Combine(FolderPath, "vbaProject.bin"), zipEntry.Name); zipFile.CommitUpdate(); zipFile.Close(); } else { var destCf = new CompoundFile(fs, CFSUpdateMode.Update, CFSConfiguration.Default); var destVbaProject = destCf.GetAllNamedEntries("_VBA_PROJECT_CUR").FirstOrDefault() as CFStorage ?? destCf.GetAllNamedEntries("OutlookVbaData").FirstOrDefault() as CFStorage ?? destCf.GetAllNamedEntries("Macros").FirstOrDefault() as CFStorage; var ls = new List <string>(); destVbaProject.VisitEntries(i => ls.Add(i.Name), true); while (ls.Count > 0) { DeleteStorageChildren(destVbaProject); ls.Clear(); destVbaProject.VisitEntries(i => ls.Add(i.Name), true); } CopyCfStreamsExcept(cf.RootStorage, destVbaProject, null); destCf.Commit(); //destCf.Save(fs); destCf.Close(); } } finally { fs?.Dispose(); } } }
void changesGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) { var sel = (Patch)ChangesGrid.SelectedItem; var fileName = sel.ModuleName + (sel.ChangeType != ChangeType.ChangeFormControls ? ModuleProcessing.ExtensionFromType(sel.ModuleType) : ".frx"); string oldPath; string newPath; if (Session.Action == ActionType.Extract) { oldPath = Path.Combine(Session.FolderPath, fileName); newPath = Path.Combine(_evf.FolderPath, fileName); } else { oldPath = Path.Combine(_evf.FolderPath, fileName); newPath = Path.Combine(Session.FolderPath, fileName); } if (sel.ChangeType == ChangeType.ChangeFormControls) { string explain; Lib.FrxFilesAreDifferent(oldPath, newPath, out explain); MessageBox.Show(explain, "FRX file difference", MessageBoxButton.OK, MessageBoxImage.Information); } else { var diffExePath = Environment.ExpandEnvironmentVariables(Session.DiffTool); if (!File.Exists(oldPath) || !File.Exists(newPath) || !File.Exists(diffExePath)) { return; } var p = new Process { StartInfo = new ProcessStartInfo(diffExePath, Session.DiffToolParameters.Replace("{OldFile}", oldPath).Replace("{NewFile}", newPath)) { UseShellExecute = false } }; p.Start(); } }
public VbaFolder(string path, IDictionary <string, string> compareModules) { if (string.IsNullOrEmpty(path)) { throw new ArgumentException("Path to file cannot be null or empty.", nameof(path)); } FileStream fs = null; try { fs = new FileStream(path, FileMode.Open); FolderPath = $"{Path.GetTempPath()}VBASync-{Guid.NewGuid()}"; Directory.CreateDirectory(FolderPath); CFStorage vbaProject; if (Path.GetFileName(path).Equals("vbaProject.bin", StringComparison.InvariantCultureIgnoreCase)) { vbaProject = new CompoundFile(fs).RootStorage; } else { var sig = new byte[4]; fs.Read(sig, 0, 4); if (sig.SequenceEqual(new byte[] { 0x50, 0x4b, 0x03, 0x04 })) { var zipFile = new ZipFile(fs); var zipEntry = zipFile.Cast <ZipEntry>().FirstOrDefault(e => e.Name.EndsWith("vbaProject.bin", StringComparison.InvariantCultureIgnoreCase)); if (zipEntry == null) { throw new ApplicationException("Cannot find 'vbaProject.bin' in ZIP archive."); } using (var sw = File.Create(Path.Combine(FolderPath, "vbaProject.bin"))) { StreamUtils.Copy(zipFile.GetInputStream(zipEntry), sw, new byte[4096]); } fs.Dispose(); fs = new FileStream(Path.Combine(FolderPath, "vbaProject.bin"), FileMode.Open); vbaProject = new CompoundFile(fs).RootStorage; } else { fs.Seek(0, SeekOrigin.Begin); vbaProject = new CompoundFile(fs).GetAllNamedEntries("_VBA_PROJECT_CUR").FirstOrDefault() as CFStorage ?? new CompoundFile(fs).GetAllNamedEntries("OutlookVbaData").FirstOrDefault() as CFStorage ?? new CompoundFile(fs).GetAllNamedEntries("Macros").FirstOrDefault() as CFStorage; } } if (vbaProject == null) { throw new ApplicationException("Cannot find VBA project storage in file."); } var projectLk = vbaProject.TryGetStream("PROJECTlk"); if (projectLk != null) { File.WriteAllBytes(Path.Combine(FolderPath, "LicenseKeys.bin"), projectLk.GetData()); } var projEncoding = Encoding.Default; uint projSysKind = 1; var projVersion = new Version(1, 1); var projConstants = new List <string>(); string currentRefName = null; var references = new List <Reference>(); var originalLibIds = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase); var modules = new List <Module>(); Module currentModule = null; var projStrings = new List <string>(); using (var br = new BinaryReader(new MemoryStream(DecompressStream(vbaProject.GetStorage("VBA").GetStream("dir"))))) { Action <int> seek = i => br.BaseStream.Seek(i, SeekOrigin.Current); while (br.BaseStream.Position < br.BaseStream.Length) { switch (br.ReadUInt16()) { case 0x0001: // PROJECTSYSKIND seek(4); // seek past size (always 4) projSysKind = br.ReadUInt32(); break; case 0x0002: case 0x0014: case 0x0008: case 0x0007: // PROJECTLCID, PROJECTLCIDINVOKE, PROJECTLIBFLAGS, and PROJECTHELPCONTEXT seek(8); // seek past whole record (always 8 bytes long) break; case 0x0003: // PROJECTCODEPAGE seek(4); // seek past size (always 4) projEncoding = Encoding.GetEncoding(br.ReadInt16()); break; case 0x0004: // PROJECTNAME seek(br.ReadInt32()); // seek past whole record, since its contents are already in PROJECT break; case 0x0005: case 0x0006: // PROJECTDOCSTRING and PROJECTHELPFILEPATH seek(br.ReadInt32() + 2); // seek past whole record, since its contents are already in PROJECT seek(br.ReadInt32()); break; case 0x0009: // PROJECTVERSION seek(4); // seek past Reserved projVersion = new Version(br.ReadInt32(), br.ReadInt16()); break; case 0x000c: // PROJECTCONSTANTS seek(br.ReadInt32() + 2); // seek past Constants and Reserved projConstants.AddRange(Encoding.Unicode.GetString(br.ReadBytes(br.ReadInt32())).Split(':').Select(s => s.Trim())); if (projConstants.Count == 1 && string.IsNullOrEmpty(projConstants[0])) { projConstants.RemoveAt(0); } break; case 0x0016: // REFERENCENAME seek(br.ReadInt32() + 2); // seek past Name and Reserved currentRefName = Encoding.Unicode.GetString(br.ReadBytes(br.ReadInt32())); break; case 0x0033: // REFERENCEORIGINAL originalLibIds.Add(currentRefName, projEncoding.GetString(br.ReadBytes(br.ReadInt32()))); break; case 0x002f: // REFERENCECONTROL (after optional REFERENCEORIGINAL) seek(4); // seek past SizeTwiddled var libIdTwiddled = projEncoding.GetString(br.ReadBytes(br.ReadInt32())); seek(6); // seek past Reserved1 and Reserved2 string nameRecordExtended = null; if (br.PeekChar() == 0x16) { // an optional REFERENCENAME record seek(2); // seek past Id seek(br.ReadInt32() + 2); // seek past Name and Reserved nameRecordExtended = Encoding.Unicode.GetString(br.ReadBytes(br.ReadInt32())); } seek(6); // seek past Reserved3 and SizeExtended var libIdExtended = projEncoding.GetString(br.ReadBytes(br.ReadInt32())); seek(6); // seek past Reserved4 and Reserved5 var originalTypeLib = new Guid(br.ReadBytes(16)); var cookie = br.ReadUInt32(); var refCtl = new ReferenceControl { Name = currentRefName, Cookie = cookie, LibIdExtended = libIdExtended, LibIdTwiddled = libIdTwiddled, NameRecordExtended = nameRecordExtended, OriginalTypeLib = originalTypeLib }; if (originalLibIds.ContainsKey(currentRefName)) { refCtl.OriginalLibId = originalLibIds[currentRefName]; } references.Add(refCtl); break; case 0x000d: // REFERENCEREGISTERED seek(4); // seek past Size references.Add(new ReferenceRegistered { Name = currentRefName, LibId = projEncoding.GetString(br.ReadBytes(br.ReadInt32())) }); seek(6); // seek past Reserved1 and Reserved2 break; case 0x000e: // REFERENCEPROJECT seek(4); // seek past Size references.Add(new ReferenceProject { Name = currentRefName, LibIdAbsolute = projEncoding.GetString(br.ReadBytes(br.ReadInt32())), LibIdRelative = projEncoding.GetString(br.ReadBytes(br.ReadInt32())), Version = new Version(br.ReadInt32(), br.ReadInt16()) }); break; case 0x000f: // PROJECTMODULES seek(6); // ignore entire record break; case 0x0013: // PROJECTCOOKIE seek(6); // ignore entire record break; case 0x0019: // MODULENAME seek(br.ReadInt32()); // ignore entire record break; case 0x0047: // MODULENAMEUNICODE modules.Add(currentModule = new Module { Name = Encoding.Unicode.GetString(br.ReadBytes(br.ReadInt32())) }); break; case 0x001a: // MODULESTREAMNAME seek(br.ReadInt32() + 2); // seek past StreamName and Reserved currentModule.StreamName = Encoding.Unicode.GetString(br.ReadBytes(br.ReadInt32())); break; case 0x001c: // MODULEDOCSTRING - ignore since this info is already in the module itself seek(br.ReadInt32() + 2); // seek past DocString and Reserved seek(br.ReadInt32()); // seek past DocStringUnicode break; case 0x0031: // MODULEOFFSET seek(4); // seek past size (always 4) currentModule.Offset = br.ReadUInt32(); break; case 0x001e: // MODULEHELPCONTEXT seek(8); // seek past entire record - this information is in the module itself as well break; case 0x002c: // MODULECOOKIE seek(6); // ignore entire record break; case 0x0021: // MODULETYPE - procedural flag seek(4); // ignore entire record since we get information about this from the PROJECT stream break; case 0x0022: // MODULETYPE - document, class, or designer flag seek(4); // ignore entire record since we get information about this from the PROJECT stream break; case 0x0025: // MODULEREADONLY currentModule.ReadOnly = true; seek(4); // seek past Reserved break; case 0x0028: // MODULEPRIVATE currentModule.Private = true; seek(4); // seek past Reserved break; case 0x002b: // module terminator currentModule = null; seek(4); break; case 0x0010: // global terminator seek(4); break; default: seek(-2); throw new ApplicationException($"Unknown record id '0x{br.ReadInt16().ToString("X4")}'."); } } } using (var sr = new StreamReader(new MemoryStream(vbaProject.GetStream("PROJECT").GetData()), projEncoding)) { string line; while ((line = sr.ReadLine()) != null) { var split = line.Split('='); var breakLoop = false; switch (split[0]?.ToUpperInvariant()) { case "MODULE": modules.First(m => string.Equals(m.Name, split[1], StringComparison.InvariantCultureIgnoreCase)) .Type = ModuleType.Standard; break; case "DOCUMENT": var split2 = split[1].Split('/'); var mod = modules.First(m => string.Equals(m.Name, split2[0], StringComparison.InvariantCultureIgnoreCase)); mod.Type = ModuleType.StaticClass; mod.Version = uint.Parse(split2[1].Substring(2), NumberStyles.HexNumber); break; case "CLASS": modules.First(m => string.Equals(m.Name, split[1], StringComparison.InvariantCultureIgnoreCase)) .Type = ModuleType.Class; break; case "BASECLASS": modules.First(m => string.Equals(m.Name, split[1], StringComparison.InvariantCultureIgnoreCase)) .Type = ModuleType.Form; break; default: if (line.Equals("[Workspace]", StringComparison.InvariantCultureIgnoreCase)) { breakLoop = true; // don't output all the cruft after [Workspace] } else { projStrings.Add(line); } break; } if (breakLoop) { break; } } } DeleteBlankLinesFromEnd(projStrings); projStrings.Insert(0, $"Version={projVersion}"); projStrings.Insert(0, $"SysKind={projSysKind}"); projStrings.Insert(0, $"CodePage={projEncoding.CodePage}"); projStrings.Add(""); projStrings.Add("[Constants]"); projStrings.AddRange(projConstants.Select(s => string.Join("=", s.Split('=').Select(t => t.Trim())))); if (modules.Any(m => m.Version > 0)) { projStrings.Add(""); projStrings.Add("[DocTLibVersions]"); projStrings.AddRange(modules.Where(m => m.Version > 0).Select(m => $"{m.Name}={m.Version}")); } foreach (var refer in references) { projStrings.Add(""); projStrings.Add($"[Reference {refer.Name}]"); projStrings.AddRange(refer.GetConfigStrings()); } File.WriteAllLines(Path.Combine(FolderPath, "Project.ini"), projStrings, projEncoding); ModuleTexts = new Dictionary <string, Tuple <string, ModuleType> >(); foreach (var m in modules) { var moduleText = projEncoding.GetString(DecompressStream(vbaProject.GetStorage("VBA").GetStream(m.StreamName), m.Offset)); if (compareModules.ContainsKey(m.Name)) { moduleText = ModuleProcessing.FixCase(compareModules[m.Name], moduleText); } moduleText = (GetPrepend(m, vbaProject, projEncoding) + moduleText).TrimEnd('\r', '\n') + "\r\n"; ModuleTexts.Add(m.Name, Tuple.Create(moduleText, m.Type)); File.WriteAllText(Path.Combine(FolderPath, m.Name + ModuleProcessing.ExtensionFromType(m.Type)), moduleText, projEncoding); } foreach (var m in modules.Where(mod => mod.Type == ModuleType.Form)) { var cf = new CompoundFile(); CopyCfStreamsExcept(vbaProject.GetStorage(m.StreamName), cf.RootStorage, "\x0003VBFrame"); var frxPath = Path.Combine(FolderPath, m.Name + ".frx"); cf.Save(frxPath); var bytes = File.ReadAllBytes(frxPath); var size = new FileInfo(frxPath).Length; using (var bw = new BinaryWriter(new FileStream(frxPath, FileMode.Open))) { bw.Write((short)0x424c); bw.Write(new byte[3]); bw.Write(size >> 8); bw.Write(new byte[11]); bw.Write(bytes); } } } finally { fs.Dispose(); } }
void applyButton_Click(object sender, RoutedEventArgs e) { var vm = ChangesGrid.DataContext as ChangesViewModel; if (vm == null) { return; } if (Session.Action == ActionType.Extract) { foreach (var p in vm.Where(p => p.Commit).ToArray()) { var fileName = p.ModuleName + ModuleProcessing.ExtensionFromType(p.ModuleType); switch (p.ChangeType) { case ChangeType.DeleteFile: File.Delete(Path.Combine(Session.FolderPath, fileName)); if (p.ModuleType == ModuleType.Form) { File.Delete(Path.Combine(Session.FolderPath, p.ModuleName + ".frx")); } break; case ChangeType.ChangeFormControls: File.Copy(Path.Combine(_evf.FolderPath, p.ModuleName + ".frx"), Path.Combine(Session.FolderPath, p.ModuleName + ".frx"), true); break; default: File.Copy(Path.Combine(_evf.FolderPath, fileName), Path.Combine(Session.FolderPath, fileName), true); if (p.ChangeType == ChangeType.AddFile && p.ModuleType == ModuleType.Form) { File.Copy(Path.Combine(_evf.FolderPath, p.ModuleName + ".frx"), Path.Combine(Session.FolderPath, p.ModuleName + ".frx"), true); } break; } vm.Remove(p); } } else { foreach (var p in vm.Where(p => p.Commit).ToArray()) { var fileName = p.ModuleName + ModuleProcessing.ExtensionFromType(p.ModuleType); switch (p.ChangeType) { case ChangeType.DeleteFile: File.Delete(Path.Combine(_evf.FolderPath, fileName)); if (p.ModuleType == ModuleType.Form) { File.Delete(Path.Combine(_evf.FolderPath, p.ModuleName + ".frx")); } break; case ChangeType.ChangeFormControls: File.Copy(Path.Combine(Session.FolderPath, p.ModuleName + ".frx"), Path.Combine(_evf.FolderPath, p.ModuleName + ".frx"), true); break; default: File.Copy(Path.Combine(Session.FolderPath, fileName), Path.Combine(_evf.FolderPath, fileName), true); if (p.ChangeType == ChangeType.AddFile && p.ModuleType == ModuleType.Form) { File.Copy(Path.Combine(Session.FolderPath, p.ModuleName + ".frx"), Path.Combine(_evf.FolderPath, p.ModuleName + ".frx"), true); } break; } vm.Remove(p); } _evf.Write(Session.FilePath); } UpdateIncludeAllBox(); }