From b3d31418ff12f4d292826ae4e157b0a54d9658d0 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Tue, 9 Apr 2019 22:30:17 +0200 Subject: [PATCH] More fixes and removal of inno setup stuff --- builders/windows-builder.py | 19 ++-- windows/OpenLP-base.wxs | 4 +- windows/OpenLP.iss.default | 187 ------------------------------------ windows/config-appveyor.ini | 1 - windows/config.ini.default | 2 - windows/psvince.dll | Bin 36864 -> 0 bytes 6 files changed, 12 insertions(+), 201 deletions(-) delete mode 100644 windows/OpenLP.iss.default delete mode 100644 windows/psvince.dll diff --git a/builders/windows-builder.py b/builders/windows-builder.py index 574cb8c..7cb1b84 100644 --- a/builders/windows-builder.py +++ b/builders/windows-builder.py @@ -119,7 +119,7 @@ class WindowsBuilder(Builder): if not parts: return dir_dict[search_key] else: - return walk_dirs(dir_dict[search_key], os.sep.join(parts)) + return self._walk_dirs(dir_dict[search_key], os.sep.join(parts)) else: return None @@ -143,19 +143,22 @@ class WindowsBuilder(Builder): dir_id = 'dir_{parent}_{base}'.format(parent=parent.replace(os.sep, '_'), base=base) element = E.Directory(Id=dir_id, Name=base) new_dir = {'__dir__': element} - parent_dir = walk_dirs(directories, parent) + parent_dir = self._walk_dirs(directories, parent) parent_dir[base] = new_dir parent_dir['__dir__'].append(element) for fname in files: source = os.path.join(path, fname) if path else fname - file_id = 'file_{source}'.format(source=source.replace('-', '_').replace(os.sep, '_')) + source = source.replace('-', '_').replace(os.sep, '_') + file_id = 'file_{source}'.format(source=source) + component_id = 'cmp_{source}'.format(source=source) file_ = E.File(Id=file_id, KeyPath="yes", Source=source) - component = E.Component(file_, Id='cmp_' + fixed_id, Guid='*') + component = E.Component(file_, Id=component_id, Guid='*') element.append(component) components.append(component) files_fragment = E.Fragment(directories[start_path]['__dir__']) - comps_fragment = E.Fragment(E.ComponentGroup(*[E.ComponentRef(Id=c.attrib['Id']) for c in components], Id='Files')) + comps_fragment = E.Fragment(E.ComponentGroup(*[E.ComponentRef(Id=c.attrib['Id']) for c in components], + Id='Files')) return files_fragment, comps_fragment def _create_wix_file(self): @@ -167,13 +170,13 @@ class WindowsBuilder(Builder): self._print_verbose('Reading base WiX file') with open(os.path.join(config_dir, 'OpenLP-base.wxs'), 'rt') as base_file: xml = base_file.read() - xml = xml.format(dialog=os.path.join(config_dir, 'WizardMain.bmp'), + xml = xml % dict(dialog=os.path.join(config_dir, 'WizardMain.bmp'), banner=os.path.join(config_dir, 'WizardBanner.bmp')) tree = fromstring(xml) self._print_verbose('Creating XML fragments from files and directories') fragments = self._get_fragments_from_files(self.dist_path) self._print_verbose('Inserting XML fragments into base WiX file') - wix = base_tree.getroot() + wix = tree.getroot() for fragment in fragments: wix.append(fragment) self._print_verbose('Writing new WiX file') @@ -353,8 +356,6 @@ class WindowsBuilder(Builder): copy(self.icon_path, os.path.join(self.dist_path, 'OpenLP.ico')) self._print_verbose('... LICENSE.txt') copy(self.license_path, os.path.join(self.dist_path, 'LICENSE.txt')) - self._print_verbose('... psvince.dll') - copy(self.psvince_exe, os.path.join(self.dist_path, 'psvince.dll')) if os.path.isfile(os.path.join(self.helpfile_path, 'OpenLP.chm')): self._print_verbose('... OpenLP.chm') copy(os.path.join(self.helpfile_path, 'OpenLP.chm'), os.path.join(self.dist_path, 'OpenLP.chm')) diff --git a/windows/OpenLP-base.wxs b/windows/OpenLP-base.wxs index d56b20d..ffda505 100644 --- a/windows/OpenLP-base.wxs +++ b/windows/OpenLP-base.wxs @@ -21,8 +21,8 @@ Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed - - + + diff --git a/windows/OpenLP.iss.default b/windows/OpenLP.iss.default deleted file mode 100644 index 0543626..0000000 --- a/windows/OpenLP.iss.default +++ /dev/null @@ -1,187 +0,0 @@ -; Script generated by the Inno Setup Script Wizard. -; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! - -#define AppName "OpenLP" -#define AppVerName "OpenLP %(display_version)s" -#define AppVersion "%(display_version)s" -#define AppPublisher "OpenLP Developers" -#define AppURL "http://openlp.org/" -#define AppExeName "OpenLP.exe" -#define Arch "%(arch)s" - -#define FileHandle FileOpen("%(branch)s\dist\OpenLP\.version") -#define FileLine FileRead(FileHandle) -#define RealVersion FileLine -#expr FileClose(FileHandle) - -[Setup] -; NOTE: The value of AppId uniquely identifies this application. -; Do not use the same AppId value in installers for other applications. -; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) -AppID={{AA7699FA-B2D2-43F4-8A70-D497D03C9485} -AppName={#AppName} -AppVerName={cm:NameAndVersion,{#AppName},{#AppVersion}} -AppVersion={#AppVersion} -AppPublisher={#AppPublisher} -AppPublisherURL={#AppURL} -AppSupportURL={#AppURL} -AppUpdatesURL={#AppURL} -DefaultDirName={pf}\{#AppName} -DefaultGroupName={#AppName} -AllowNoIcons=true -LicenseFile=LICENSE.txt -OutputDir=%(branch)s\dist\ -OutputBaseFilename=OpenLP-{#RealVersion}-{#Arch}-setup -Compression=lzma/Max -SolidCompression=true -SetupIconFile=OpenLP.ico -VersionInfoVersion={#AppVersion} -WizardImageFile=WizImageBig.bmp -WizardSmallImageFile=WizImageSmall.bmp -ChangesAssociations=true - -[Languages] -Name: english; MessagesFile: compiler:Default.isl -Name: brazilianportuguese; MessagesFile: compiler:Languages\BrazilianPortuguese.isl -Name: catalan; MessagesFile: compiler:Languages\Catalan.isl -Name: czech; MessagesFile: compiler:Languages\Czech.isl -Name: danish; MessagesFile: compiler:Languages\Danish.isl -Name: dutch; MessagesFile: compiler:Languages\Dutch.isl -Name: finnish; MessagesFile: compiler:Languages\Finnish.isl -Name: french; MessagesFile: compiler:Languages\French.isl -Name: german; MessagesFile: compiler:Languages\German.isl -Name: hebrew; MessagesFile: compiler:Languages\Hebrew.isl -Name: hungarian; MessagesFile: compiler:Languages\Hungarian.isl -Name: italian; MessagesFile: compiler:Languages\Italian.isl -Name: japanese; MessagesFile: compiler:Languages\Japanese.isl -Name: norwegian; MessagesFile: compiler:Languages\Norwegian.isl -Name: polish; MessagesFile: compiler:Languages\Polish.isl -Name: portuguese; MessagesFile: compiler:Languages\Portuguese.isl -Name: russian; MessagesFile: compiler:Languages\Russian.isl -Name: slovenian; MessagesFile: compiler:Languages\Slovenian.isl -Name: spanish; MessagesFile: compiler:Languages\Spanish.isl - -[Tasks] -Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons} -Name: quicklaunchicon; Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons}; OnlyBelowVersion: 0, 6.1 - -[Files] -Source: %(branch)s\dist\OpenLP\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs -; DLL used to check if the target program is running at install time -Source: psvince.dll; flags: dontcopy -; psvince is installed in {app} folder, so it will be loaded at -; uninstall time to check if the target program is running -Source: psvince.dll; DestDir: {app} - -[Icons] -Name: {group}\{#AppName}; Filename: {app}\{#AppExeName} -Name: {group}\{#AppName} (Debug); Filename: {app}\{#AppExeName}; Parameters: -l debug -Name: {group}\{#AppName} Help; Filename: {app}\{#AppName}.chm; Check: FileExists(ExpandConstant('{app}\{#AppName}.chm')) -Name: {group}\{cm:ProgramOnTheWeb,{#AppName}}; Filename: {#AppURL} -Name: {group}\{cm:UninstallProgram,{#AppName}}; Filename: {uninstallexe} -Name: {commondesktop}\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: desktopicon -Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: quicklaunchicon - -[Run] -Filename: {app}\{#AppExeName}; Description: {cm:LaunchProgram,{#AppName}}; Flags: nowait postinstall skipifsilent - -[Registry] -Root: HKCR; Subkey: .osz; ValueType: string; ValueName: ; ValueData: OpenLP; Flags: uninsdeletevalue -Root: HKCR; Subkey: .oszl; ValueType: string; ValueName: ; ValueData: OpenLP; Flags: uninsdeletevalue -Root: HKCR; Subkey: OpenLP; ValueType: string; ValueName: ; ValueData: OpenLP Service; Flags: uninsdeletekey -Root: HKCR; Subkey: OpenLP\DefaultIcon; ValueType: string; ValueName: ; ValueData: {app}\OpenLP.exe,0 -Root: HKCR; Subkey: OpenLP\shell\open\command; ValueType: string; ValueName: ; ValueData: """{app}\OpenLP.exe"" ""%1""" - -[UninstallDelete] -; Remove support directory created when program is run: -Type: filesandordirs; Name: {app}\support -; Remove program directory if empty: -Name: {app}; Type: dirifempty - -[Code] -// Function to call psvince.dll at install time -function IsModuleLoadedInstall(modulename: AnsiString ): Boolean; -external 'IsModuleLoaded@files:psvince.dll stdcall setuponly'; - -// Function to call psvince.dll at uninstall time -function IsModuleLoadedUninstall(modulename: AnsiString ): Boolean; -external 'IsModuleLoaded@{app}\psvince.dll stdcall uninstallonly' ; - -function GetUninstallString(): String; -var - sUnInstPath: String; - sUnInstallString: String; -begin - sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); - sUnInstallString := ''; - if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then - RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); - Result := sUnInstallString; -end; - -function IsUpgrade(): Boolean; -begin - Result := (GetUninstallString() <> ''); -end; - -// Return Values: -// 1 - uninstall string is empty -// 2 - error executing the UnInstallString -// 3 - successfully executed the UnInstallString -function UnInstallOldVersion(): Integer; -var - sUnInstallString: String; - iResultCode: Integer; -begin - Result := 0; - sUnInstallString := GetUninstallString(); - if sUnInstallString <> '' then - begin - sUnInstallString := RemoveQuotes(sUnInstallString); - if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then - Result := 3 - else - Result := 2; - end - else - Result := 1; -end; - -function InitializeSetup(): Boolean; -begin - Result := true; - while IsModuleLoadedInstall( 'OpenLP.exe' ) and Result do - begin - if MsgBox( 'Openlp is currently running, please close it to continue the install.', - mbError, MB_OKCANCEL ) = IDCANCEL then - begin - Result := false; - end; - end; -end; - -procedure CurStepChanged(CurStep: TSetupStep); -begin - if (CurStep=ssInstall) then - begin - if (IsUpgrade()) then - begin - UnInstallOldVersion(); - end; - end; -end; - -function InitializeUninstall(): Boolean; -begin - Result := true; - while IsModuleLoadedUninstall( 'OpenLP.exe' ) and Result do - begin - if MsgBox( 'Openlp is currently running, please close it to continue the uninstall.', - mbError, MB_OKCANCEL ) = IDCANCEL then - begin - Result := false; - end; - end; -// Unload psvince.dll, otherwise it is not deleted - UnloadDLL(ExpandConstant('{app}\psvince.dll')); -end; diff --git a/windows/config-appveyor.ini b/windows/config-appveyor.ini index 3062bd2..85e4e73 100644 --- a/windows/config-appveyor.ini +++ b/windows/config-appveyor.ini @@ -2,7 +2,6 @@ sphinx = %(pyroot)s\Scripts\sphinx-build.exe pyinstaller = %(pyroot)s\Scripts\pyinstaller-script.py htmlhelp = %(progfiles)s\HTML Help Workshop\hhc.exe -psvince = %(here)s\psvince.dll lrelease = C:\Qt\5.12\msvc2017\bin\lrelease.exe portablelauncher = %(here)s\..\..\PortableApps.comLauncher\PortableApps.comLauncherGenerator.exe portableinstaller = %(here)s\..\..\PortableApps.comInstaller\PortableApps.comInstaller.exe diff --git a/windows/config.ini.default b/windows/config.ini.default index 7b67dc3..22a9804 100644 --- a/windows/config.ini.default +++ b/windows/config.ini.default @@ -1,9 +1,7 @@ [executables] -innosetup = %(progfiles)s\Inno Setup 5\ISCC.exe sphinx = %(pyroot)s\Scripts\sphinx-build.exe pyinstaller = %(here)s\..\pyinstaller\pyinstaller.py htmlhelp = %(progfiles)s\HTML Help Workshop\hhc.exe -psvince = %(here)s\psvince.dll lrelease = %(sitepackages)s\PyQt5\bin\lrelease.exe portablelauncher = %(progfiles)s\PortableApps.comLauncher\PortableApps.comLauncherGenerator.exe portableinstaller = %(progfiles)s\PortableApps.comInstaller\PortableApps.comInstaller.exe diff --git a/windows/psvince.dll b/windows/psvince.dll deleted file mode 100644 index e910509d0dfff5e99e12dbdd1a56bf3b5aadd5ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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