def tryCopyFile(sourceFilePath, destFilePath):
    if not sourceFilePath.startswith('\\\\'):
        sourceFilePath = u"\\\\?\\" + sourceFilePath
    if not destFilePath.startswith('\\\\'):
        destFilePath = u"\\\\?\\" + destFilePath
    if windll.kernel32.CopyFileW(sourceFilePath, destFilePath, False) == 0:
        errorCode = GetLastError()
        log.debugWarning("Unable to copy %s, error %d" %
                         (sourceFilePath, errorCode))
        if not os.path.exists(destFilePath):
            raise OSError("error %d copying %s to %s" %
                          (errorCode, sourceFilePath, destFilePath))
        tempPath = tempfile.mktemp(dir=os.path.dirname(destFilePath))
        try:
            os.rename(destFilePath, tempPath)
        except (WindowsError, OSError):
            log.error("Failed to rename %s after failed overwrite" %
                      destFilePath,
                      exc_info=True)
            raise RetriableFailure(
                "Failed to rename %s after failed overwrite" % destFilePath)
        winKernel.moveFileEx(tempPath, None,
                             winKernel.MOVEFILE_DELAY_UNTIL_REBOOT)
        if windll.kernel32.CopyFileW(sourceFilePath, destFilePath, False) == 0:
            errorCode = GetLastError()
            raise OSError("Unable to copy file %s to %s, error %d" %
                          (sourceFilePath, destFilePath, errorCode))
def tryRemoveFile(path,numRetries=6,retryInterval=0.5,rebootOK=False):
	dirPath=os.path.dirname(path)
	tempPath=tempfile.mktemp(dir=dirPath)
	try:
		os.rename(path,tempPath)
	except (WindowsError,IOError):
		raise RetriableFailure("Failed to rename file %s before  remove"%path)
	for count in range(numRetries):
		try:
			if os.path.isdir(tempPath):
				shutil.rmtree(tempPath)
			else:
				os.remove(tempPath)
			return
		except OSError:
			pass
		time.sleep(retryInterval)
	if rebootOK:
		log.debugWarning("Failed to delete file %s, marking for delete on reboot"%tempPath)
		try:
			# Use escapes in a unicode string instead of raw.
			# In a raw string the trailing slash escapes the closing quote leading to a python syntax error.
			pathQualifier=u"\\\\?\\"
			# #9847: Move file to None to delete it.
			winKernel.moveFileEx(pathQualifier+tempPath,None,winKernel.MOVEFILE_DELAY_UNTIL_REBOOT)
		except WindowsError:
			log.debugWarning("Failed to delete file %s, marking for delete on reboot"%tempPath, exc_info=True)
		return
	try:
		os.rename(tempPath,path)
	except:
		log.error("Unable to rename back to %s before retriable failier"%path)
	raise RetriableFailure("File %s could not be removed"%path)
Beispiel #3
0
 def onPostponeButton(self, evt):
     finalDest = os.path.join(storeUpdatesDir,
                              os.path.basename(self.destPath))
     try:
         # #9825: behavior of os.rename(s) has changed (see https://bugs.python.org/issue28356).
         # In Python 2, os.renames did rename files across drives, no longer allowed in Python 3 (error 17 (cannot move files across drives) is raised).
         # This is prominent when trying to postpone an update for portable copy of NVDA if this runs from a USB flash drive or another internal storage device.
         # Therefore use kernel32::MoveFileEx with copy allowed (0x2) flag set.
         winKernel.moveFileEx(self.destPath, finalDest,
                              winKernel.MOVEFILE_COPY_ALLOWED)
     except:
         log.debugWarning("Unable to rename the file from {} to {}".format(
             self.destPath, finalDest),
                          exc_info=True)
         gui.messageBox(
             # Translators: The message when a downloaded update file could not be preserved.
             _("Unable to postpone update."),
             # Translators: The title of the message when a downloaded update file could not be preserved.
             _("Error"),
             wx.OK | wx.ICON_ERROR)
         finalDest = self.destPath
     state["pendingUpdateFile"] = finalDest
     state["pendingUpdateVersion"] = self.version
     state["pendingUpdateAPIVersion"] = self.apiVersion
     state["pendingUpdateBackCompatToAPIVersion"] = self.backCompatTo
     # Postponing an update indicates that the user is likely interested in getting a reminder.
     # Therefore, clear the dontRemindVersion.
     state["dontRemindVersion"] = None
     saveState()
     self.EndModal(wx.ID_CLOSE)
Beispiel #4
0
def FaultTolerantFile(name):
    '''Used to write out files in a more fault tolerant way. A temporary file is used, and replaces the 
	file `name' when the context manager scope ends and the the context manager __exit__ is called. This
	means writing out the complete file can be performed with less concern of corrupting the original file
	if the process is interrupted by windows shutting down.
	`name` must be unicode.

	Usage:
		with FaultTolerantFile("myFile.txt") as f:
			f.write("This is a test")

	This creates a temporary file, and the writes actually happen on this temp file. At the end of the 
	`with` block, when `f` goes out of context the temporary file is closed and, this temporary file replaces "myFile.txt"
	'''
    if not isinstance(name, text_type):
        raise TypeError("name must be an unicode string")
    dirpath, filename = os.path.split(name)
    with NamedTemporaryFile(dir=dirpath,
                            prefix=filename,
                            suffix='.tmp',
                            delete=False) as f:
        log.debug(f.name)
        yield f
        f.flush()
        os.fsync(f)
        f.close()
        winKernel.moveFileEx(f.name, name, winKernel.MOVEFILE_REPLACE_EXISTING)