def main(): """Execute Main program.""" parser = argparse.ArgumentParser(description='Trim MSI.') parser.add_argument('file', type=argparse.FileType('r'), help='file to trim') parser.add_argument('out', type=argparse.FileType('w'), help='file to output to') args = parser.parse_args() print("Trimming MSI") db = msilib.OpenDatabase(args.file.name, msilib.MSIDBOPEN_DIRECT) exec_delete( db, "select * from ControlEvent WHERE Dialog_ = 'LicenseAgreementDlg' AND Control_ = 'Next' AND Event = 'NewDialog' AND Argument = 'CustomizeDlg'" ) exec_delete( db, "select * from ControlEvent WHERE Dialog_ = 'CustomizeDlg' AND Control_ = 'Back' AND Event = 'NewDialog' AND Argument = 'LicenseAgreementDlg'" ) exec_delete( db, "select * from ControlEvent WHERE Dialog_ = 'CustomizeDlg' AND Control_ = 'Next' AND Event = 'NewDialog' AND Argument = 'VerifyReadyDlg'" ) exec_delete( db, "select * from ControlEvent WHERE Dialog_ = 'VerifyReadyDlg' AND Control_ = 'Back' AND Event = 'NewDialog' AND Argument = 'CustomizeDlg'" ) db.Commit() shutil.copyfile(args.file.name, args.out.name)
def main(): # Check arguments parser = argparse.ArgumentParser( description='Embed .mst transform into the MSI database.') parser.add_argument('storageName', metavar='storageName', help="The name of the storage (language name)") parser.add_argument('databasePath', metavar='databasePath', help="Path to MSI in which to embed") parser.add_argument('importPath', metavar='importPath', help="Path to transform file (.mst)") args = parser.parse_args() # Open database and create a view on the _Storages table sqlQuery = "SELECT `Name`,`Data` FROM _Storages" database = msilib.OpenDatabase(args.databasePath, 1) view = database.OpenView(sqlQuery) # Create and Insert the row with 2 fields. record = msilib.CreateRecord(2) record.SetString(1, args.storageName) view.Execute(record) # Insert storage - copy data into stream record.SetStream(2, args.importPath) view.Modify(3, record) database.Commit()
def getMsiProperty(path, property): print(path) db = msilib.OpenDatabase(path, msilib.MSIDBOPEN_READONLY) view = db.OpenView("SELECT Value FROM Property WHERE Property='" + property + "'") view.Execute(None) result = view.Fetch() return result.GetString(1)
def generate_MSI(self): shutil.copy(self.template, self.msifile.path) #1 Add exe and ini file to cab filelist = [(self.exefile.path, "ExeFile"), (self.inifile.path, "IniFile")] cabfile = os.path.join(self.tempdir, "files.cab") msilib.FCICreate(cabfile, filelist) #2 Open the MSI database #database = msilib.init_database(self.msifile.path, msilib.schema, self.msifile.name, self.productcode, self.productversion, self.manufacturer) #print self.msifile.path #msilib.add_tables(database, msilib.schema) database = msilib.OpenDatabase(self.msifile.path, msilib.MSIDBOPEN_DIRECT) msilib.add_stream(database, "Wpkg_GP.cab", cabfile) # Update Product Code summaryinformation = database.GetSummaryInformation(1) summaryinformation.SetProperty(msilib.PID_REVNUMBER, self.package_GUID) summaryinformation.Persist() # Add information to Media # DiskId | LastSequence | DiskPrompt | Cabinet | VolumeLabel | Source table = "Media" records = [(1, 2, None, "#Wpkg_GP.cab", None, None)] msilib.add_data(database, table, records) #CAB = msilib.CAB("Wpkg_GP.cab") #CAB.append(self.exefile.path, "ExeFile", "ExeFile") #CAB.append(self.inifile.path, "IniFile", "IniFile") #CAB.commit(database) # Add information to File # File | Component_ | FileName | FileSize| Version | Language | Attributes | Sequence table = "File" records = [("ExeFile", "Installer", self.exefile.name, self.exefile.size, None, None, 512, 1), ("IniFile", "Installer", self.inifile.name, self.inifile.size, None, None, 512, 2)] msilib.add_data(database, table, records) # Add information to CustomAction # Action | Type | Source | Target # For Type, see: http://msdn.microsoft.com/en-us/library/aa372048%28v=VS.85%29.aspx # Add information to Property # Property | Value # Update version view = database.OpenView( "UPDATE Property SET Value='%s' WHERE Property='ProductVersion'" % self.exefile.get_fileversion_as_string()) view.Execute(None) view = database.OpenView( "UPDATE Property Set Value='%s' WHERE Property='ProductCode'" % self.product_GUID) view.Execute(None) database.Commit()
def GetProductVersion(srcMsi): logging.info("start to get ProductVersion from: " + str(srcMsi)) msi_DB = msilib.OpenDatabase(srcMsi, msilib.MSIDBOPEN_READONLY) view = msi_DB.OpenView( "SELECT Value FROM Property WHERE Property='ProductVersion'") view.Execute(None) record = view.Fetch() productVersion = record.GetString(1) return productVersion
def GetFeatureParent(srcMsi): logging.info("start to get FeatureParent from: " + str(srcMsi)) msiDB = msilib.OpenDatabase(srcMsi, msilib.MSIDBOPEN_TRANSACT) view = msiDB.OpenView( "SELECT Feature FROM Feature WHERE Feature_Parent=''") view.Execute(None) record = view.Fetch() FeatureName = record.GetString(1) return FeatureName
def get_property_msi(self, path, msi_property): """read property from msi file""" # https://stackoverflow.com/a/9768876/861745 msi_db = msilib.OpenDatabase(path, msilib.MSIDBOPEN_READONLY) view = msi_db.OpenView("SELECT Value FROM Property WHERE Property='" + msi_property + "'") view.Execute(None) result = view.Fetch() self.output(dir(result), 3) return result.GetString(1)
def AddSPComponent(msiSrcPath, patch_level): try: FeatureName = GetFeatureParent(msiSrcPath) logger.info("FeatureName :" + str(FeatureName)) componUUID = msilib.gen_uuid() patchName = str(patchType) + str(patch_level) logger.info("patchName :" + str(patchName)) sp_product_name = '[ProductName] ' + patchName logger.info("sp_product_name :" + str(sp_product_name)) patch_reg_key = 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\' + sp_product_name MsiProductCode = GetProductCode(msiSrcPath) msiDB = msilib.OpenDatabase(msiSrcPath, msilib.MSIDBOPEN_TRANSACT) #add component for SP msilib.add_data( msiDB, 'Component', [(patchName + '_RegistryUninstall', componUUID, 'INSTALLDIR', 260, 'PATCH', patchName + '_UNINSTALLSTRING')]) msilib.add_data(msiDB, 'FeatureComponents', [(FeatureName, patchName + '_RegistryUninstall')]) msilib.add_data(msiDB, 'Registry', [ (patchName + '_UNINSTALLSTRING', 2, patch_reg_key, 'UninstallString', 'Msiexec.exe /uninstall ' + str(PatchUUID) + ' /package [ProductCode] /qb', patchName + '_RegistryUninstall'), (patchName + '_SHELL_ENTRY', 2, patch_reg_key, '*', '', patchName + '_RegistryUninstall'), (patchName + '_DISPLAYICON', 2, patch_reg_key, 'DisplayIcon', '[SetupFolder]SetupRes\\amar.ico', patchName + '_RegistryUninstall'), (patchName + '_DISPLAYNAME', 2, patch_reg_key, 'DisplayName', '[ProductName] ' + patchName + '-64bit ', patchName + '_RegistryUninstall'), (patchName + '_DISPLAYVERSION', 2, patch_reg_key, 'DisplayVersion', '[ProductVersion]', patchName + '_RegistryUninstall'), (patchName + '_NOMODIFY', 2, patch_reg_key, 'NoModify', '#1', patchName + '_RegistryUninstall'), (patchName + '_NOREMOVE', 2, patch_reg_key, 'NoRemove', '#0', patchName + '_RegistryUninstall'), (patchName + '_NOREPAIR', 2, patch_reg_key, 'NoRepair', '#1', patchName + '_RegistryUninstall'), (patchName + '_PARENTDISPLAYNAME', 2, patch_reg_key, 'ParentDisplayName', '[ProductName]', patchName + '_RegistryUninstall'), (patchName + '_PARENTKEYNAME', 2, patch_reg_key, 'ParentKeyName', '[ProductName]', patchName + '_RegistryUninstall'), (patchName + '_INSTALLDATE', 2, patch_reg_key, 'InstallDate', '[Date]', patchName + '_RegistryUninstall'), (patchName + '_RELEASETYPE', 2, patch_reg_key, 'ReleaseType', 'Product Update', patchName + '_RegistryUninstall'), (patchName + '_PUBLISHER', 2, patch_reg_key, 'Publisher', '[Manufacturer]', patchName + '_RegistryUninstall') ]) msiDB.Commit() except Exception as E: logger.info("Exception in AddSPComponent is:" + str(E))
def SetHotfixUpgradeMSIProductVersion(srcMsi, baseVersion): logging.info("start to SetHotfixUpgradeMSIProductVersion from: " + str(srcMsi) + "baseVersion: " + str(baseVersion)) msiDB = msilib.OpenDatabase(srcMsi, msilib.MSIDBOPEN_TRANSACT) version = baseVersion view = msiDB.OpenView( "UPDATE Property SET Value='%s' WHERE Property='ProductVersion'" % (version)) view.Execute(None) view.Close() msiDB.Commit()
def WiSubStg(baseMsi, langId): database = msilib.OpenDatabase(baseMsi, msilib.MSIDBOPEN_TRANSACT) view = database.OpenView("SELECT `Name`,`Data` FROM _Storages") record = msilib.CreateRecord(2) record.SetString(1, langId) view.Execute(record) record.SetStream(2, langId + '.mst') view.Modify(msilib.MSIMODIFY_ASSIGN, record) database.Commit() view = None database = None
def WiLangId(baseMsi, sumInfoStream): database = msilib.OpenDatabase(baseMsi, msilib.MSIDBOPEN_TRANSACT) sumInfo = database.GetSummaryInformation(1) template = sumInfo.GetProperty(7).decode() iDelim = template.find(';') platform = ';' if 0 <= iDelim: platform = template[0:iDelim + 1] sumInfo.SetProperty(7, platform + sumInfoStream) sumInfo.Persist() database.Commit() database = None
def set_serial(filename, license): db = msilib.OpenDatabase(filename, msilib.MSIDBOPEN_DIRECT) sql = "select * from Property WHERE `Property`='GUILIC'" view = db.OpenView(sql) view.Execute(None) rec = view.Fetch() rec.SetString(2, license) view.Modify(msilib.MSIMODIFY_REPLACE, rec) view.Close() db.Commit()
def get_msi_properties(msi_filename): db = msilib.OpenDatabase(msi_filename, msilib.MSIDBOPEN_READONLY) view = db.OpenView("SELECT * FROM Property") view.Execute(None) result = {} r = view.Fetch() while r: try: result[r.GetString(1)] = r.GetString(2) except: print "erreur pour %s" % r.GetString(0) try: r = view.Fetch() except: break return result
def generate_msi(self, document, dstroot): """ generate msi from a document, using systescanmerge and registryscanmerge """ self.database = msilib.OpenDatabase(self.msiFile.path, msilib.MSIDBOPEN_DIRECT) self.document = document propertyRecords = self.collectPropertyRecords() table = "Property" msilib.add_data(self.database, table, propertyRecords) promptText = self.productName + " " + self.productVersion + " [1]" diskPrompt = [ ("DiskPrompt", promptText ) ] msilib.add_data(self.database, table, diskPrompt) self.cabFile = msilib.CAB("files.cab") f = msilib.Feature(self.database, "defaultFeature", "Default Feature", "Everything", 0, directory="TARGETDIR") f.set_current() home = dstroot[:3] # example home = "C:\" # this is the root directory object, a parent of all subdirs in the installation root = msilib.Directory(self.database, self.cabFile, None, home , "TARGETDIR", "SourceDir") self.__buildMSIHiarchy(dstroot, root) # create a component in "Component" table responsible for installing the registry keys root.start_component(component = self.RegsitryComponent, flags = 0) # RegsitryComponent is set to current component by default, we don't need that right now, root.component = None # Create and add registry records: self.createRegistryRecords() if len(self.registryRecords) != 0: # there are registry changes, enable and then add them to the installer actionsRecords = self.enableRegistryActions() table = "InstallExecuteSequence" msilib.add_data(self.database, table, actionsRecords) # now add self.registryRecords found by calling createRegistryRecords, to the msi. a list of tuples is the format. table = "Registry" msilib.add_data(self.database, table, self.registryRecords) self.database.Commit() self.cabFile.commit(self.database)
def GetLanguagePackCode(srcMsi): try: logging.info("start to get GetISLanguagePack from: " + str(srcMsi)) msi_DB = msilib.OpenDatabase(srcMsi, msilib.MSIDBOPEN_READONLY) view = msi_DB.OpenView( "SELECT Value FROM Property WHERE Property='SETUP_ISLANGUAGEPACK'") view.Execute(None) record = view.Fetch() ISLanguagePack = record.GetString(1) view = msi_DB.OpenView( "SELECT Value FROM Property WHERE Property='ProductLanguage'") view.Execute(None) record = view.Fetch() LanguagePackCode = record.GetString(1) return ISLanguagePack, LanguagePackCode except Exception as E: logger.info("Exception in GetLanguagePackCode is:" + str(E)) return "false", "false"
def main(): try: msi_s = sys.argv[1] except IndexError: msi_s = input('Paste MSI path: ') db = msilib.OpenDatabase(msi_s, msilib.MSIDBOPEN_READONLY) v = db.OpenView("select Value from Property where Property='ProductCode'") v.Execute(None) col_index = 0 col_info = v.GetColumnInfo(msilib.MSICOLINFO_NAMES) while True: if col_info.GetString(col_index) == 'Value': break col_index += 1 row = v.Fetch() guid = row.GetString(col_index) print('Product code:', guid) v.Close()
def WriteCode(baseMsi, ver4Dot, code, vcver): database = msilib.OpenDatabase(baseMsi, msilib.MSIDBOPEN_READONLY) view = database.OpenView( "SELECT `Value` FROM Property WHERE `Property`='ProductCode'") record = msilib.CreateRecord(1) view.Execute(record) data = view.Fetch() view = None database = None prodcode = data.GetString(1) if len(prodcode) > 0: d = datetime.datetime.now().isoformat(' ') codes = open(AgilityBookDir + r'\Misc\InstallGUIDs.csv', 'a') installs = '' if code == code64: installs = 'VC' + vcver + ',x64' else: installs = 'VC' + vcver + ',win32' print('v' + ver4Dot + ',' + d + ',' + prodcode + ',' + UpgradeCode + ',' + installs, file=codes)
def updateFromMSI(args): debug("Archive: %s", args.archive) debug("Target: %s", args.target) debug("msi: %s", args.msi) debug("7z.exe: %s", args.sevenZip) info("Replacing binaries in '%s' from '%s'", args.archive, args.msi) msidir = tempfile.mkdtemp() archdir = tempfile.mkdtemp() try: debug("Reading '%s' msi database", args.msi) msidb = msilib.OpenDatabase(args.msi, msilib.MSIDBOPEN_READONLY) # Reference: # http://msdn.microsoft.com/en-us/library/windows/desktop/aa368596%28v=vs.85%29.aspx # A helpful tool for looking into an msi can be found at: # http://code.google.com/p/lessmsi/ view = msidb.OpenView("SELECT File, FileName FROM File") view.Execute(None) msifiles = {} # Original filename -> MSI filename mapping try: while True: row = view.Fetch() if not row: break rowFile = row.GetString(1) # Not 0 based rowFileNames = row.GetString(2).split( '|') # Short and long filename are seperated by | if len(rowFileNames) > 1: longRowFileName = rowFileNames[1] msifiles[longRowFileName] = rowFile else: shortRowFileName = rowFileNames[0] msifiles[shortRowFileName] = rowFile except msilib.MSIError as e: # Unfortunately this always happens when we reach the end while fetching # 0x103 is ERROR_NO_MORE_ITEMS, no idea why we get that as an exception # instead of a None on Fetch if not e.message == 'unknown error 103': raise pass debug("Done") debug("Extract '%s' msi file", args.msi) result = call([args.sevenZip, 'e', '-bd', '-o' + msidir, args.msi]) if result != 0: error("Failed to extract msi '%d'", result) return result debug("Done") debug("Extract '%s' archive file", args.archive) result = call( [args.sevenZip, 'x', '-bd', '-o' + archdir, args.archive]) if result != 0: error("Failed to extract archive '%d'", result) return result debug("Done") debug("Replacing binary files") for (dirpath, dirnames, filenames) in os.walk(archdir): for filename in filenames: if os.path.splitext(filename)[1] in ['.exe', '.dll']: # Check for replacement in flat msi directory msifilename = msifiles.get(filename) if msifilename: msifile = os.path.join(msidir, msifilename) archfile = os.path.join(dirpath, filename) debug("Replacing '%s' with '%s'", filename, msifilename) copy(msifile, archfile) else: warning("Found no replacement match for '%s'", filename) debug("Done") debug("Re-packing archive") abstarget = os.path.abspath(args.target) # Since we started with an archive to begin with and only performed replacements # no filtering is needed result = call([args.sevenZip, 'a', '-bd', '-r', abstarget], cwd=archdir) if result != 0: error("Failed to re-pack archive from '%s' to '%s'", archdir, args.target) return result debug("Done") finally: rmtree(msidir) rmtree(archdir) return 0
view = db.OpenView(query) view.Execute(None) cur_record = view.Fetch() view.Modify(msilib.MSIMODIFY_DELETE, cur_record) view.Close() def exec_update(query, column, value): view = db.OpenView(query) view.Execute(None) cur_record = view.Fetch() cur_record.SetString(column, value) view.Modify(msilib.MSIMODIFY_REPLACE, cur_record) view.Close() print "Trimming MSI" db = msilib.OpenDatabase(args.file.name, msilib.MSIDBOPEN_DIRECT) exec_delete("select * from ControlEvent WHERE Dialog_ = 'LicenseAgreementDlg' AND Control_ = 'Next' AND Event = 'NewDialog' AND Argument = 'CustomizeDlg'") exec_delete("select * from ControlEvent WHERE Dialog_ = 'CustomizeDlg' AND Control_ = 'Back' AND Event = 'NewDialog' AND Argument = 'LicenseAgreementDlg'") exec_update("select * from ControlEvent WHERE Dialog_ = 'VerifyReadyDlg' AND Control_ = 'Back' AND Event = 'NewDialog' AND Argument = 'CustomizeDlg'", 5, "WixUI_InstallMode = \"InstallCustom\"") db.Commit() shutil.copyfile(args.file.name, args.out.name);
def fixmsi(f): db = msilib.OpenDatabase(f, msilib.MSIDBOPEN_DIRECT) v = db.OpenView('UPDATE RegLocator SET Type = 18 WHERE Type = 2') v.Execute(None) v.Close() db.Commit()