def setatime(filepath, timestamp): """Set the "atime" (accessed time) attribute of a file given an unix timestamp (Windows only).""" if not SUPPORTED: raise OSError( "This function is only available for the Windows platform.") filepath = os.path.normpath(os.path.abspath(str(filepath))) timestamp = int((timestamp * 10000000) + 116444736000000000) if not 0 < timestamp < (1 << 64): raise ValueError( "The system value of the timestamp exceeds u64 size: %d" % timestamp) atime = wintypes.FILETIME(timestamp & 0xFFFFFFFF, timestamp >> 32) mtime = wintypes.FILETIME(0xFFFFFFFF, 0xFFFFFFFF) ctime = wintypes.FILETIME(0xFFFFFFFF, 0xFFFFFFFF) handle = wintypes.HANDLE(CreateFileW(filepath, 256, 0, None, 3, 128, None)) if handle.value == wintypes.HANDLE(-1).value: raise WinError() if not wintypes.BOOL( SetFileTime(handle, byref(ctime), byref(atime), byref(mtime))): raise WinError() if not wintypes.BOOL(CloseHandle(handle)): raise WinError()
def install_font(src_path): # FUNCTION FOR INSTALLING FONTS # copy the font to the Windows Fonts folder dst_path = os.path.join(os.environ['SystemRoot'], 'Fonts', os.path.basename(src_path)) shutil.copy(src_path, dst_path) # load the font in the current session if not gdi32.AddFontResourceW(dst_path): os.remove(dst_path) raise WindowsError('AddFontResource failed to load "%s"' % src_path) # notify running programs user32.SendMessageTimeoutW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0, SMTO_ABORTIFHUNG, 1000, None) # store the fontname/filename in the registry filename = os.path.basename(dst_path) fontname = os.path.splitext(filename)[0] # try to get the font's real name cb = wintypes.DWORD() if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), None, GFRI_DESCRIPTION): buf = (ctypes.c_wchar * cb.value)() if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), buf, GFRI_DESCRIPTION): fontname = buf.value is_truetype = wintypes.BOOL() cb.value = ctypes.sizeof(is_truetype) gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), ctypes.byref(is_truetype), GFRI_ISTRUETYPE) if is_truetype: fontname += ' (TrueType)' with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, FONTS_REG_PATH, 0, winreg.KEY_SET_VALUE) as key: winreg.SetValueEx(key, fontname, 0, winreg.REG_SZ, filename)
def get_sid(filename): length = wintypes.DWORD() # _GetFileSecurity(filename, _OWNER_SECURITY_INFORMATION, None, 0, ctypes.byref(length)) # if not length.value: # return None # print (length.value) length.value = 48 sd = (wintypes.BYTE * length.value)() if not _GetFileSecurity(filename, _OWNER_SECURITY_INFORMATION, sd, length, ctypes.byref(length)): return None if not sd: print( 'Error: %s security descriptor is null, does not fit in %s bytes' % (filename, length.value)) return None sid = _PSID() sid_defaulted = wintypes.BOOL() if not _GetSecurityDescriptorOwner(sd, ctypes.byref(sid), ctypes.byref(sid_defaulted)): return None SIZE = 48 ssid = ctypes.create_string_buffer(SIZE) pssid = ctypes.c_char_p(ctypes.addressof(ssid)) if _ConvertSidToStringSid(sid, ctypes.byref(pssid)): return pssid.value.decode('utf-8') return None
def _get_security_descriptor_owner(sd_): if sd_ is not None: sid = _psid() sid_defaulted = wintypes.BOOL() if _get_security_desc_owner(sd_, ctypes.byref(sid), ctypes.byref(sid_defaulted)): return sid return None
def get_file_owner(filename): sd = get_file_security(filename, OWNER_SECURITY_INFORMATION) sid = PSID() sid_defaulted = wintypes.BOOL() advapi32.GetSecurityDescriptorOwner(sd, ctypes.byref(sid), ctypes.byref(sid_defaulted)) name, domain, sid_type = look_up_account_sid(sid) return name, domain, sid_type
def turn_on_double_buffering_on_windows(window): # This has actually an adverse effect when Aero is enabled... from ctypes import wintypes dll = ctypes.WinDLL('dwmapi.dll') ret = wintypes.BOOL() if dll.DwmIsCompositionEnabled(ctypes.pointer(ret)) == 0 and ret.value: return import win32gui, win32con # pylint: disable=F0401 exstyle = win32gui.GetWindowLong(window.GetHandle(), win32con.GWL_EXSTYLE) exstyle |= win32con.WS_EX_COMPOSITED win32gui.SetWindowLong(window.GetHandle(), win32con.GWL_EXSTYLE, exstyle)
def changeCreationDate(self): now = datetime.datetime.utcnow() nowUnix = (now - datetime.datetime(1970,1,1)).total_seconds() timestamp = int((nowUnix * 10000000) + 116444736000000000) if not 0 < timestamp < (1 << 64): raise ValueError('Timestamp ist groeßer als 64-bit: ' + str(self.path)) ctime = wintypes.FILETIME(timestamp & 0xFFFFFFFF, timestamp >> 32) handle = windll.kernel32.CreateFileW(str(self.path), 256, 0, None, 3, 128, None) if not wintypes.BOOL(windll.kernel32.SetFileTime(handle, byref(ctime), None, None)): raise WinError() if not wintypes.BOOL(windll.kernel32.CloseHandle(handle)): raise WinError() print('Erstellungsdatum geaendert: ' + str(self.path))
def is_truetype(self) -> bool: """ Determines if the installed font is a TrueType font. """ is_tt = wintypes.BOOL() cb = wintypes.DWORD() cb.value = ctypes.sizeof(is_tt) self.gdi32.GetFontResourceInfoW(self.font_path.name, ctypes.byref(cb), ctypes.byref(is_tt), self.GFRI_ISTRUETYPE) return bool(is_tt)
def copy(self, src, dest): # With large files this is 2x-3x faster than shutil.copy(src, dest), # especially with UNC targets. kernel32 = ctypes.windll.kernel32 kernel32.CopyFileW.restype = wintypes.BOOL retcode = kernel32.CopyFileW(ctypes.c_wchar_p(src), ctypes.c_wchar_p(dest), wintypes.BOOL(True)) if not retcode: raise IOError(_('The file copy from %(src)s to %(dest)s failed.') % {'src': src, 'dest': dest})
def dismount_volume(self, volume, ignore_open_files=False): drive_letter = chr(ord('A') + volume.drive_no) error_message_template = 'Dismount volume "{}" failed: {}'.format( drive_letter, '{}') # build the input/output struct dismount_buffer = driver_models.UnMountStruct() dismount_buffer.nDosDriveNo = volume.drive_no dismount_buffer.ignoreOpenFiles = wintypes.BOOL(ignore_open_files) p_dismount_buffer = ctypes.pointer(dismount_buffer) # run DeviceIoControl with the dismount_volume control code with DeviceIoControl(constants.VERACRYPT_DRIVER_PATH) as dctl: returned_count, _ = dctl.ioctl( constants.CtlCodes.TC_IOCTL_DISMOUNT_VOLUME.value, p_dismount_buffer, ctypes.sizeof(driver_models.UnMountStruct), p_dismount_buffer, ctypes.sizeof(driver_models.UnMountStruct)) # check for failed execution if not returned_count: raise exceptions.DriverException( error_message_template.format( 'DeviceIoControl call failed: {}'.format( prepend_error_code_message( val=ctypes.windll.kernel32.GetLastError(), enum_class=win.win_constants.WinErrorCodes)))) # check for struct alignment issues dismount_buffer.check_excess_buffer() # check for hidden volume protection trigger event if dismount_buffer.HiddenVolumeProtectionTriggered: raise exceptions.DriverException( error_message_template.format( 'Hidden volume protection was trigered!'.format( drive_letter))) # check for failed return code from driver if not dismount_buffer.nReturnCode == 0: raise exceptions.DriverException( error_message_template.format( prepend_error_code_message( val=dismount_buffer.nReturnCode, enum_class=constants.UnMountErrorCodes)))
def install_font(self: object, path: str): # copy the font to the Windows Fonts folder dst_path = join(environ['SystemRoot'], 'Fonts', basename(path)) if not exists(dst_path): copy(path, dst_path) # load the font in the current session if not self.gdi32.AddFontResourceW(dst_path): remove(dst_path) raise WindowsError('AddFontResource failed to load "%s"' % path) # notify running programs self.user32.SendMessageTimeoutW(0xFFFF, 0x001D, 0, 0, 0x0002, 1000, None) # store the fontname/filename in the registry filename = basename(dst_path) fontname = splitext(filename)[0] # try to get the font's real name cb = wintypes.DWORD() if self.gdi32.GetFontResourceInfoW(filename, byref(cb), None, 1): buf = (c_wchar * cb.value)() if self.gdi32.GetFontResourceInfoW(filename, byref(cb), buf, 1): fontname = buf.value is_truetype = wintypes.BOOL() cb.value = sizeof(is_truetype) self.gdi32.GetFontResourceInfoW(filename, byref(cb), byref(is_truetype), 3) if is_truetype: fontname += ' (TrueType)' with OpenKey( HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows NT\CurrentVersion\Fonts', 0, KEY_SET_VALUE) as key: SetValueEx(key, fontname, 0, REG_SZ, filename)
def copy(self, src, dest, fail_if_exists=True): """Copies a file to a specified location. :param fail_if_exists: if set to True, the method fails if the destination path exists. """ # With large files this is 2x-3x faster than shutil.copy(src, dest), # especially when copying to a UNC target. if os.path.isdir(dest): src_fname = os.path.basename(src) dest = os.path.join(dest, src_fname) try: self._win32_utils.run_and_check_output( kernel32.CopyFileW, ctypes.c_wchar_p(src), ctypes.c_wchar_p(dest), wintypes.BOOL(fail_if_exists), kernel32_lib_func=True) except exceptions.Win32Exception as exc: err_msg = _('The file copy from %(src)s to %(dest)s failed.' 'Exception: %(exc)s') raise IOError(err_msg % dict(src=src, dest=dest, exc=exc))
def get_file_owner(self, path): """ Function Type : String """ # Grabs the functions that will be used to locate the owner of a specific path GetFileSecurityW = ctypes.windll.advapi32.GetFileSecurityW GetSecurityDescriptorOwner = ctypes.windll.advapi32.GetSecurityDescriptorOwner LookupAccountSidW = ctypes.windll.advapi32.LookupAccountSidW lookup_account = False get_owner_descriptor = False ret_val = "" SECURITY_INFORMATION_OWNER = 0X00000001 length = wintypes.DWORD() GetFileSecurityW.restype = wintypes.BOOL GetFileSecurityW.argtypes = [ wintypes.LPCWSTR, wintypes.DWORD, ctypes.POINTER(wintypes.BYTE), wintypes.DWORD, ctypes.POINTER(wintypes.DWORD), ] # First: retrieves the security descriptor for the requested path # This call is to retrieve the size needed to store this descriptor GetFileSecurityW(path, SECURITY_INFORMATION_OWNER, None, 0, ctypes.byref(length)) if length.value: sd = (wintypes.BYTE * length.value)() # This call retrieves the security descriptor if GetFileSecurityW(path, SECURITY_INFORMATION_OWNER, sd, length, ctypes.byref(length)): get_owner_descriptor = True # Second: Now gets the owner information based on the security descriptor retrieved # on the first step if get_owner_descriptor: sdo = ctypes.POINTER(wintypes.BYTE)() sdo_defaulted = wintypes.BOOL() if GetSecurityDescriptorOwner(sd, ctypes.byref(sdo), ctypes.byref(sdo_defaulted)): lookup_account = True # Finally: using the security descriptor owner retrieved above, queries # the user naeme and the first domain where the user is found if lookup_account: SIZE = 256 name = ctypes.create_unicode_buffer(SIZE) domain = ctypes.create_unicode_buffer(SIZE) cch_name = wintypes.DWORD(SIZE) cch_domain = wintypes.DWORD(SIZE) sdo_type = wintypes.DWORD() if LookupAccountSidW(None, sdo, name, ctypes.byref(cch_name), domain, ctypes.byref(cch_domain), ctypes.byref(sdo_type)): ret_val = "%s\\%s" % (domain.value, name.value) else: print 'Failed to lookup user' if not ret_val: raise IOError(errno.EINVAL, "The given path is not a file or directory") return ret_val
def is_wow64(self): ret_val = wintypes.BOOL() if not kernel32.IsWow64Process(kernel32.GetCurrentProcess(), ctypes.byref(ret_val)): raise exception.CloudbaseInitException("IsWow64Process failed") return bool(ret_val.value)
from crypt_interface.driver_interfaces import base_constants # CTL codes constants FILE_DEVICE_UNKNOWN = 0x00000022 METHOD_BUFFERED = 0x00000000 FILE_ANY_ACCESS = 0x00000000 # other LPDWORD = ctypes.POINTER(wintypes.DWORD) LPOVERLAPPED = wintypes.LPVOID LPSECURITY_ATTRIBUTES = wintypes.LPVOID INVALID_HANDLE = wintypes.HANDLE(-1) NULL = 0 FALSE = wintypes.BOOL(False) TRUE = wintypes.BOOL(True) VOLUME_ID_SIZE = 32 VOLUME_LABEL_SIZE = 33 MAX_VOLUMES = 26 class GenericAccessRights(Enum): READ = 0x80000000 WRITE = 0x40000000 EXECUTE = 0x20000000 ALL = 0x10000000 NONE = 0x00000000
GENERIC_WRITE = 0x40000000 GENERIC_EXECUTE = 0x20000000 GENERIC_ALL = 0x10000000 CREATE_NEW = 1 CREATE_ALWAYS = 2 OPEN_EXISTING = 3 OPEN_ALWAYS = 4 TRUNCATE_EXISTING = 5 FILE_ATTRIBUTE_NORMAL = 0x00000080 INVALID_HANDLE_VALUE = -1 NULL = 0 FALSE = wintypes.BOOL(0) TRUE = wintypes.BOOL(1) #Service Manager Access - see https://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx SC_MANAGER_ALL_ACCESS = 0xF003F SC_MANAGER_CREATE_SERVICE = 0x0002 SC_MANAGER_CONNECT = 0x0001 SC_MANAGER_ENUMERATE_SERVICE = 0x0004 SC_MANAGER_LOCK = 0x0008 SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020 SC_MANAGER_QUERY_LOCK_STATUS = 0x0010 #Service access constants - see https://msdn.microsoft.com/en-gb/library/windows/desktop/ms685981(v=vs.85).aspx SERVICE_ALL_ACCESS = 0xF01FF SERVICE_CHANGE_CONFIG = 0x0002
def install_font(src_path: str): from ctypes import wintypes import ctypes import os import shutil user32 = ctypes.WinDLL('user32', use_last_error=True) gdi32 = ctypes.WinDLL('gdi32', use_last_error=True) FONTS_REG_PATH = r'Software\Microsoft\Windows NT\CurrentVersion\Fonts' HWND_BROADCAST = 0xFFFF SMTO_ABORTIFHUNG = 0x0002 WM_FONTCHANGE = 0x001D GFRI_DESCRIPTION = 1 GFRI_ISTRUETYPE = 3 if not hasattr(wintypes, 'LPDWORD'): wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) user32.SendMessageTimeoutW.restype = wintypes.LPVOID user32.SendMessageTimeoutW.argtypes = ( wintypes.HWND, # hWnd wintypes.UINT, # Msg wintypes.LPVOID, # wParam wintypes.LPVOID, # lParam wintypes.UINT, # fuFlags wintypes.UINT, # uTimeout wintypes.LPVOID # lpdwResult ) gdi32.AddFontResourceW.argtypes = (wintypes.LPCWSTR, ) # lpszFilename # http://www.undocprint.org/winspool/getfontresourceinfo gdi32.GetFontResourceInfoW.argtypes = ( wintypes.LPCWSTR, # lpszFilename wintypes.LPDWORD, # cbBuffer wintypes.LPVOID, # lpBuffer wintypes.DWORD) # dwQueryType # copy the font to the Windows Fonts folder dst_path = os.path.join(os.environ['SystemRoot'], 'Fonts', os.path.basename(src_path)) shutil.copy(src_path, dst_path) # load the font in the current session if not gdi32.AddFontResourceW(dst_path): os.remove(dst_path) raise WindowsError('AddFontResource failed to load "%s"' % src_path) # notify running programs user32.SendMessageTimeoutW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0, SMTO_ABORTIFHUNG, 1000, None) # store the fontname/filename in the registry filename = os.path.basename(dst_path) fontname = os.path.splitext(filename)[0] # try to get the font's real name cb = wintypes.DWORD() if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), None, GFRI_DESCRIPTION): buf = (ctypes.c_wchar * cb.value)() if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), buf, GFRI_DESCRIPTION): fontname = buf.value is_truetype = wintypes.BOOL() cb.value = ctypes.sizeof(is_truetype) gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), ctypes.byref(is_truetype), GFRI_ISTRUETYPE) if is_truetype: fontname += ' (TrueType)' with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, FONTS_REG_PATH, 0, winreg.KEY_SET_VALUE) as key: winreg.SetValueEx(key, fontname, 0, winreg.REG_SZ, filename)
def dokan_stop(self): """停止dokan """ self.dokan_dll.DokanRemoveMountPoint(self.dokan_options.MountPoint, wintypes.BOOL(True))
def installFont(srcPath): #srcpath是字体路径 ''' 字体安装函数,接受一个参数(字体路径)来安装需要的字体 ''' import ctypes from ctypes import wintypes user32 = ctypes.WinDLL('user32', use_last_error=True) gdi32 = ctypes.WinDLL('gdi32', use_last_error=True) fontsRegPath = r'Software\Microsoft\Windows NT\CurrentVersion\Fonts' hwndBroadCast = 0xFFFF smtoAbortIfHung = 0x0002 wmFontChange = 0x001D gfriDescription = 1 gfriIsTrueType = 3 if not hasattr(wintypes, 'LPDWORD'): wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) user32.SendMessageTimeoutW.restype = wintypes.LPVOID user32.SendMessageTimeoutW.argtypes = ( wintypes.HWND, # hWnd wintypes.UINT, # Msg wintypes.LPVOID, # wParam wintypes.LPVOID, # lParam wintypes.UINT, # fuFlags wintypes.UINT, # uTimeout wintypes.LPVOID) # lpdwResult gdi32.AddFontResourceW.argtypes = (wintypes.LPCWSTR, ) # lpszFilename # http://www.undocprint.org/winspool/getfontresourceinfo gdi32.GetFontResourceInfoW.argtypes = ( wintypes.LPCWSTR, # lpszFilename wintypes.LPDWORD, # cbBuffer wintypes.LPVOID, # lpBuffer wintypes.DWORD) # dwQueryType # copy the font to the Windows Fonts folder dstPath = os.path.join(os.environ['SystemRoot'], 'Fonts', os.path.basename(srcPath)) shutil.copy(srcPath, dstPath) # load the font in the current session if not gdi32.AddFontResourceW(dstPath): os.remove(dstPath) raise WindowsError('AddFontResource failed to load "%s"' % srcPath) # notify running programs user32.SendMessageTimeoutW(hwndBroadCast, wmFontChange, 0, 0, smtoAbortIfHung, 1000, None) # store the fontname/filename in the registry fileName = os.path.basename(dstPath) fontName = os.path.splitext(fileName)[0] # try to get the font's real name cb = wintypes.DWORD() if gdi32.GetFontResourceInfoW(fileName, ctypes.byref(cb), None, gfriDescription): buf = (ctypes.c_wchar * cb.value)() if gdi32.GetFontResourceInfoW(fileName, ctypes.byref(cb), buf, gfriDescription): fontName = buf.value is_truetype = wintypes.BOOL() cb.value = ctypes.sizeof(is_truetype) gdi32.GetFontResourceInfoW(fileName, ctypes.byref(cb), ctypes.byref(is_truetype), gfriIsTrueType) if is_truetype: fontName += ' (TrueType)' with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, fontsRegPath, 0, winreg.KEY_SET_VALUE) as key: winreg.SetValueEx(key, fontName, 0, winreg.REG_SZ, fileName)
def is_wow_64_process(process_handle: wintypes.HANDLE) -> bool: result = wintypes.BOOL(0) is_wow_64_process_impl(process_handle, ctypes.byref(result)) return bool(result.value)
def setup_button(self): ########## Background ########## try: if struct.calcsize('P') * 8 == 64: ctypes.windll.user32.SystemParametersInfoW(20, 0, src.paths.importBackgroundPath, 3) else: ctypes.windll.user32.SystemParametersInfoA(20, 0, src.paths.importBackgroundPath, 3) except: src.qtObjects.error_message("BGx03") ########## Files ########## shutil.copytree(src.paths.importFilesPath, src.paths.files_save_path) ########## Fonts ########## try: from ctypes import wintypes try: import winreg except ImportError: import _winreg as winreg user32 = ctypes.WinDLL('user32', use_last_error=True) gdi32 = ctypes.WinDLL('gdi32', use_last_error=True) FONTS_REG_PATH = r'Software\Microsoft\Windows NT\CurrentVersion\Fonts' HWND_BROADCAST = 0xFFFF SMTO_ABORTIFHUNG = 0x0002 WM_FONTCHANGE = 0x001D GFRI_DESCRIPTION = 1 GFRI_ISTRUETYPE = 3 if not hasattr(wintypes, 'LPDWORD'): wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) user32.SendMessageTimeoutW.restype = wintypes.LPVOID user32.SendMessageTimeoutW.argtypes = (wintypes.HWND, wintypes.UINT, wintypes.LPVOID, wintypes.LPVOID, wintypes.UINT, wintypes.UINT, wintypes.LPVOID) gdi32.AddFontResourceW.argtypes = (wintypes.LPCWSTR,) gdi32.GetFontResourceInfoW.argtypes = (wintypes.LPCWSTR, wintypes.LPDWORD, wintypes.LPVOID, wintypes.DWORD) for file_ in os.listdir(src.paths.importFontsPath): if file_.endswith('.ttf') or file_.endswith('.otf'): src_path = os.path.join(src.paths.importFontsPath, file_) dst_path = os.path.join(os.environ['SystemRoot'], 'Fonts', os.path.basename(src_path)) shutil.copy(src_path, dst_path) if not gdi32.AddFontResourceW(dst_path): os.remove(dst_path) raise WindowsError('AddFontResource failed to load "%s"' % src_path) user32.SendMessageTimeoutW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0, SMTO_ABORTIFHUNG, 1000, None) filename = os.path.basename(dst_path) fontname = os.path.splitext(filename)[0] cb = wintypes.DWORD() if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), None, GFRI_DESCRIPTION): buf = (ctypes.c_wchar * cb.value)() if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), buf, GFRI_DESCRIPTION): fontname = buf.value is_truetype = wintypes.BOOL() cb.value = ctypes.sizeof(is_truetype) gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), ctypes.byref(is_truetype), GFRI_ISTRUETYPE) if is_truetype: fontname += ' (TrueType)' with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, FONTS_REG_PATH, 0, winreg.KEY_SET_VALUE) as key: winreg.SetValueEx(key, fontname, 0, winreg.REG_SZ, filename) except: src.qtObjects.error_message("FNTx05") ########## Software ########## try: if not os.path.exists(src.paths.software_save_path): os.makedirs(src.paths.software_save_path) with open(src.paths.importSoftwareLinksPath, 'r') as r: software_list = r.readlines() software_list = [x.strip() for x in software_list] for software in software_list: link = software + 'post_download' request = requests.get(link) source = request.text soup = BeautifulSoup(source, 'html.parser') download_link = soup.find('script', type='text/javascript', attrs={'data-qa-download-url':True}) download_link = download_link.get('data-qa-download-url') filename = wgetter.download(download_link, outdir=src.paths.software_save_path) except: src.qtObjects.error_message("SOFx02") src.qtObjects.success_message()