# -*- coding: utf-8 -*- import os import subprocess import ctypes import ssl import time from urllib2 import Request, urlopen BLUEBEAM_INSTALLER_URL = "https://cdn-patchportal-one.comodo.com/portal/packages/spm/Bluebeam%20Revu/x64/Bluebeam%20Revu%20x64%2021.msi" BLUEBEAM_PRODUCT_KEYWORD = "Bluebeam Revu" TEMP_DIR = os.environ.get("TEMP", "C:\\Windows\\Temp") class disable_fs_redirection: _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection def __enter__(self): self.old_value = ctypes.c_long() self.success = self._disable(ctypes.byref(self.old_value)) def __exit__(self, a, b, c): if self.success: self._revert(self.old_value) def run(cmd): with disable_fs_redirection(): p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() return out, err # ============================================================ # TRUE MSI-Level Uninstall (Fix) # ============================================================ def uninstall_all_bluebeam(): # Query Windows Installer directly query_cmd = 'wmic product where "name like \'%%%s%%\'" get IdentifyingNumber /format:list' % BLUEBEAM_PRODUCT_KEYWORD result, err = run(query_cmd) if result: for line in result.splitlines(): line = line.strip() if line.startswith("IdentifyingNumber="): guid = line.split("=")[-1].strip() if guid: uninstall_cmd = 'msiexec /x %s /qn /norestart' % guid run(uninstall_cmd) time.sleep(10) else: # fallback direct uninstall string run('MsiExec.exe /X{99588A9A-57A2-4807-9B55-6CB84E83FECA} /qn /norestart') time.sleep(10) # ============================================================ # Download and Install # ============================================================ def download_installer(path, url): req = Request(url, headers={'User-Agent': 'Mozilla/5.0'}) context = ssl._create_unverified_context() r = urlopen(req, context=context) with open(path, "wb") as f: while True: chunk = r.read(100 * 1024) if not chunk: break f.write(chunk) def install_bluebeam(): file_name = os.path.basename(BLUEBEAM_INSTALLER_URL) local_path = os.path.join(TEMP_DIR, file_name) download_installer(local_path, BLUEBEAM_INSTALLER_URL) run('msiexec /i "%s" /qn /norestart' % local_path) time.sleep(10) try: os.remove(local_path) except: pass def update_bluebeam(): uninstall_all_bluebeam() time.sleep(5) install_bluebeam()