public IDecompileResult Execute() { var result = this.Context.ServiceProvider.GetService <IDecompileResult>(); try { using (var database = new Database(this.Context.DecompilePath, OpenDatabase.ReadOnly)) { // Delete the directory and its files to prevent cab extraction failure due to an existing file. if (Directory.Exists(this.Context.ExtractFolder)) { Directory.Delete(this.Context.ExtractFolder, true); } var backendHelper = this.Context.ServiceProvider.GetService <IBackendHelper>(); var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, database, this.Context.DecompilePath, this.Context.DecompileType, this.Context.ExtractFolder, this.Context.IntermediateFolder, this.Context.IsAdminImage, suppressDemodularization: false, skipSummaryInfo: false); var output = unbindCommand.Execute(); var extractedFilePaths = new List <string>(unbindCommand.ExportedFiles); var decompiler = new Decompiler(this.Messaging, backendHelper, this.Extensions, this.Context.BaseSourcePath, this.Context.SuppressCustomTables, this.Context.SuppressDroppingEmptyTables, this.Context.SuppressUI, this.Context.TreatProductAsModule); result.Document = decompiler.Decompile(output); result.Platform = GetPlatformFromOutput(output); // extract the files from the cabinets if (!String.IsNullOrEmpty(this.Context.ExtractFolder) && !this.Context.SuppressExtractCabinets) { var fileDirectory = String.IsNullOrEmpty(this.Context.CabinetExtractFolder) ? Path.Combine(this.Context.ExtractFolder, "File") : this.Context.CabinetExtractFolder; var extractCommand = new ExtractCabinetsCommand(output, database, this.Context.DecompilePath, fileDirectory, this.Context.IntermediateFolder, this.Context.TreatProductAsModule); extractCommand.Execute(); extractedFilePaths.AddRange(extractCommand.ExtractedFiles); result.ExtractedFilePaths = extractedFilePaths; } else { result.ExtractedFilePaths = new string[0]; } } } catch (Win32Exception e) { if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED { throw new WixException(ErrorMessages.OpenDatabaseFailed(this.Context.DecompilePath)); } throw; } return(result); }
private WindowsInstallerData GetData(string path) { var ext = Path.GetExtension(path); if (".msi".Equals(ext, StringComparison.OrdinalIgnoreCase)) { using (var database = new Database(path, OpenDatabase.ReadOnly)) { var exportBasePath = Path.Combine(this.IntermediateFolder, "_msi"); // TODO: come up with a better path. var isAdminImage = false; // TODO: need a better way to set this var command = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, database, path, OutputType.Product, exportBasePath, this.IntermediateFolder, isAdminImage, suppressDemodularization: true, skipSummaryInfo: true); return(command.Execute()); } } else // assume .wixpdb (or .wixout) { var data = WindowsInstallerData.Load(path, true); return(data); } }
public Intermediate Unbind(IUnbindContext context) { #if REVISIT_FOR_PATCHING Output patch; // patch files are essentially database files (use a special flag to let the API know its a patch file) try { using (Database database = new Database(context.InputFilePath, OpenDatabase.ReadOnly | OpenDatabase.OpenPatchFile)) { var unbindCommand = new UnbindDatabaseCommand(context.Messaging, database, context.InputFilePath, OutputType.Patch, context.ExportBasePath, context.IntermediateFolder, context.IsAdminImage, context.SuppressDemodularization, skipSummaryInfo: false); patch = unbindCommand.Execute(); } } catch (Win32Exception e) { if (0x6E == e.NativeErrorCode) // ERROR_OPEN_FAILED { throw new WixException(WixErrors.OpenDatabaseFailed(context.InputFilePath)); } throw; } // retrieve the transforms (they are in substorages) using (Storage storage = Storage.Open(context.InputFilePath, StorageMode.Read | StorageMode.ShareDenyWrite)) { Table summaryInformationTable = patch.Tables["_SummaryInformation"]; foreach (Row row in summaryInformationTable.Rows) { if (8 == (int)row[0]) // PID_LASTAUTHOR { string value = (string)row[1]; foreach (string decoratedSubStorageName in value.Split(';')) { string subStorageName = decoratedSubStorageName.Substring(1); string transformFile = Path.Combine(context.IntermediateFolder, String.Concat("Transform", Path.DirectorySeparatorChar, subStorageName, ".mst")); // ensure the parent directory exists Directory.CreateDirectory(Path.GetDirectoryName(transformFile)); // copy the substorage to a new storage for the transform file using (Storage subStorage = storage.OpenStorage(subStorageName)) { using (Storage transformStorage = Storage.CreateDocFile(transformFile, StorageMode.ReadWrite | StorageMode.ShareExclusive | StorageMode.Create)) { subStorage.CopyTo(transformStorage); } } // unbind the transform var unbindCommand = new UnbindTransformCommand(context.Messaging, transformFile, (null == context.ExportBasePath ? null : Path.Combine(context.ExportBasePath, subStorageName)), context.IntermediateFolder); var transform = unbindCommand.Execute(); patch.SubStorages.Add(new SubStorage(subStorageName, transform)); } break; } } } // extract the files from the cabinets // TODO: use per-transform export paths for support of multi-product patches if (null != context.ExportBasePath && !context.SuppressExtractCabinets) { using (Database database = new Database(context.InputFilePath, OpenDatabase.ReadOnly | OpenDatabase.OpenPatchFile)) { foreach (SubStorage subStorage in patch.SubStorages) { // only patch transforms should carry files if (subStorage.Name.StartsWith("#", StringComparison.Ordinal)) { var extractCommand = new ExtractCabinetsCommand(subStorage.Data, database, context.InputFilePath, context.ExportBasePath, context.IntermediateFolder); extractCommand.Execute(); } } } } return(patch); #endif throw new NotImplementedException(); }