(self)
Generate package files for MSI installer package
Generate package files for MSI installer package
Generate package files for MSI installer package
def generate_files(self):
        '''
           Generate package files for MSI installer package
        '''
        self.root = ET.Element('Wix', {'xmlns': 'http://schemas.microsoft.com/wix/2006/wi'})
        product = ET.SubElement(self.root, 'Product', {
            'Name': self.product_name,
            'Manufacturer': 'The Meson Development Team',
            'Id': self.guid,
            'UpgradeCode': self.update_guid,
            'Language': '1033',
            'Codepage':  '1252',
            'Version': self.version,
        })

        package = ET.SubElement(product, 'Package', {
            'Id': '*',
            'Keywords': 'Installer',
            'Description': f'Meson {self.version} installer',
            'Comments': 'Meson is a high performance build system',
            'Manufacturer': 'The Meson Development Team',
            'InstallerVersion': '500',
            'Languages': '1033',
            'Compressed': 'yes',
            'SummaryCodepage': '1252',
        })

        condition = ET.SubElement(product, 'Condition', {'Message': 'This application is only supported on Windows 10 or higher.'})

        condition.text = 'X'*len(WINVER_CHECK)
        ET.SubElement(product, 'MajorUpgrade',
                      {'DowngradeErrorMessage': 'A newer version of Meson is already installed.'})

        package.set('Platform', 'x64')
        ET.SubElement(product, 'Media', {
            'Id': '1',
            'Cabinet': 'meson.cab',
            'EmbedCab': 'yes',
        })
        targetdir = ET.SubElement(product, 'Directory', {
            'Id': 'TARGETDIR',
            'Name': 'SourceDir',
        })
        progfiledir = ET.SubElement(targetdir, 'Directory', {
            'Id': self.progfile_dir,
        })
        installdir = ET.SubElement(progfiledir, 'Directory', {
            'Id': 'INSTALLDIR',
            'Name': 'Meson',
        })
        ET.SubElement(installdir, 'Merge', {
            'Id': 'VCRedist',
            'SourceFile': self.redist_path,
            'DiskId': '1',
            'Language': '0',
        })

        ET.SubElement(product, 'Property', {
            'Id': 'WIXUI_INSTALLDIR',
            'Value': 'INSTALLDIR',
        })
        ET.SubElement(product, 'UIRef', {
            'Id': 'WixUI_FeatureTree',
        })
        for s_d in self.staging_dirs:
            assert os.path.isdir(s_d)
        top_feature = ET.SubElement(product, 'Feature', {
            'Id': 'Complete',
            'Title': 'Meson ' + self.version,
            'Description': 'The complete package',
            'Display': 'expand',
            'Level': '1',
            'ConfigurableDirectory': 'INSTALLDIR',
        })
        for s_d in self.staging_dirs:
            nodes = {}
            for root, dirs, files in os.walk(s_d):
                cur_node = Node(dirs, files)
                nodes[root] = cur_node
            self.create_xml(nodes, s_d, installdir, s_d)
            self.build_features(top_feature, s_d)
        vcredist_feature = ET.SubElement(top_feature, 'Feature', {
            'Id': 'VCRedist',
            'Title': 'Visual C++ runtime',
            'AllowAdvertise': 'no',
            'Display': 'hidden',
            'Level': '1',
        })
        ET.SubElement(vcredist_feature, 'MergeRef', {'Id': 'VCRedist'})
        ET.ElementTree(self.root).write(self.main_xml, encoding='utf-8', xml_declaration=True)
        # ElementTree can not do prettyprinting so do it manually
        import xml.dom.minidom
        doc = xml.dom.minidom.parse(self.main_xml)
        with open(self.main_xml, 'w') as open_file:
            open_file.write(doc.toprettyxml())
        # One last fix, add CDATA.
        with open(self.main_xml) as open_file:
            data = open_file.read()
        data = data.replace('X'*len(WINVER_CHECK), WINVER_CHECK)
        with open(self.main_xml, 'w') as open_file:
            open_file.write(data)
def generate_files ( self ) : self . root = ET . Element ( 'Wix' , { 'xmlns' : 'http://schemas.microsoft.com/wix/2006/wi' } ) product = ET . SubElement ( self . root , 'Product' , { 'Name' : self . product_name , 'Manufacturer' : 'The Meson Development Team' , 'Id' : self . guid , 'UpgradeCode' : self . update_guid , 'Language' : '1033' , 'Codepage' : '1252' , 'Version' : self . version , } ) package = ET . SubElement ( product , 'Package' , { 'Id' : '*' , 'Keywords' : 'Installer' , 'Description' : f'Meson {self.version} installer' , 'Comments' : 'Meson is a high performance build system' , 'Manufacturer' : 'The Meson Development Team' , 'InstallerVersion' : '500' , 'Languages' : '1033' , 'Compressed' : 'yes' , 'SummaryCodepage' : '1252' , } ) condition = ET . SubElement ( product , 'Condition' , { 'Message' : 'This application is only supported on Windows 10 or higher.' } ) condition . text = 'X' * len ( WINVER_CHECK ) ET . SubElement ( product , 'MajorUpgrade' , { 'DowngradeErrorMessage' : 'A newer version of Meson is already installed.' } ) package . set ( 'Platform' , 'x64' ) ET . SubElement ( product , 'Media' , { 'Id' : '1' , 'Cabinet' : 'meson.cab' , 'EmbedCab' : 'yes' , } ) targetdir = ET . SubElement ( product , 'Directory' , { 'Id' : 'TARGETDIR' , 'Name' : 'SourceDir' , } ) progfiledir = ET . SubElement ( targetdir , 'Directory' , { 'Id' : self . progfile_dir , } ) installdir = ET . SubElement ( progfiledir , 'Directory' , { 'Id' : 'INSTALLDIR' , 'Name' : 'Meson' , } ) ET . SubElement ( installdir , 'Merge' , { 'Id' : 'VCRedist' , 'SourceFile' : self . redist_path , 'DiskId' : '1' , 'Language' : '0' , } ) ET . SubElement ( product , 'Property' , { 'Id' : 'WIXUI_INSTALLDIR' , 'Value' : 'INSTALLDIR' , } ) ET . SubElement ( product , 'UIRef' , { 'Id' : 'WixUI_FeatureTree' , } ) for s_d in self . staging_dirs : assert os . path . isdir ( s_d ) top_feature = ET . SubElement ( product , 'Feature' , { 'Id' : 'Complete' , 'Title' : 'Meson ' + self . version , 'Description' : 'The complete package' , 'Display' : 'expand' , 'Level' : '1' , 'ConfigurableDirectory' : 'INSTALLDIR' , } ) for s_d in self . staging_dirs : nodes = { } for root , dirs , files in os . walk ( s_d ) : cur_node = Node ( dirs , files ) nodes [ root ] = cur_node self . create_xml ( nodes , s_d , installdir , s_d ) self . build_features ( top_feature , s_d ) vcredist_feature = ET . SubElement ( top_feature , 'Feature' , { 'Id' : 'VCRedist' , 'Title' : 'Visual C++ runtime' , 'AllowAdvertise' : 'no' , 'Display' : 'hidden' , 'Level' : '1' , } ) ET . SubElement ( vcredist_feature , 'MergeRef' , { 'Id' : 'VCRedist' } ) ET . ElementTree ( self . root ) . write ( self . main_xml , encoding = 'utf-8' , xml_declaration = True ) # ElementTree can not do prettyprinting so do it manually import xml . dom . minidom doc = xml . dom . minidom . parse ( self . main_xml ) with open ( self . main_xml , 'w' ) as open_file : open_file . write ( doc . toprettyxml ( ) ) # One last fix, add CDATA. with open ( self . main_xml ) as open_file : data = open_file . read ( ) data = data . replace ( 'X' * len ( WINVER_CHECK ) , WINVER_CHECK ) with open ( self . main_xml , 'w' ) as open_file : open_file . write ( data )