58
Advanced UserAdvanced User
58

    Feb 28, 2005#16

    Cool. Your trick worked for the time. To make the date come out correct, I had to adjust the offsets:

    Code: Select all

    SET FLT=%time: =0% 
    COPY %1 "%1.%date:~9,4%-%date:~3,2%-%date:~6,2%_%FLT:~0,2%-%FLT:~3,2%-%FLT:~6,2%_%FLT:~9,2%.bak"
    Fortunately, there now is a RunTool command in the UE macro language. Thus a tiny macro could be created that runs this batch file whenever a file is loaded into UE.

    Manni

    81
    Advanced UserAdvanced User
    81

      Macro creating a backup before operation?

      Feb 27, 2016#17

      Say, I have a file named "abc.xml" and I want to run a macro, namely "xyz.mac". Can I add a code on the macro which will tell the macro
      to first take a backup of "abc.xml" on the same path or a desired path and then go on with the rest of the macro operations so that if
      the macro messes up the abc.xml file for some reason, I can always go back to the backup where the file is as it was before running the macro?

      6,603548
      Grand MasterGrand Master
      6,603548

        Re: Macro creating a backup before operation?

        Feb 27, 2016#18

        The following macro code can be used for creating a simple copy of existing file in directory of active file with .bak simply appended to file name before reformatting the active file with a macro.

        Code: Select all

        InsertMode
        ColumnModeOff
        HexOff
        Clipboard 8
        CopyFilePath
        Clipboard 9
        SelectAll
        Copy
        Top
        NewFile
        Paste
        ClearClipboard
        Clipboard 8
        SaveAs "^c.bak"
        CloseFile NoSave
        ClearClipboard
        Clipboard 0
        

          Feb 29, 2016#19

          After 11 years I thought it is time to update this topic with better batch file solution working for Windows XP and later Windows versions.

          First, take a look on article about comparing file times with batch code written by me on Stack Overflow if being interested in using date and time in batch files with lots of useful information.

          Running in a command prompt window the command wmic OS get /? displays what WMIC: WMI command-line utility offers on operating system related data. Most interesting for this task is: LocalDateTime.

          Running in a command prompt window WMIC OS GET LocalDateTime /format:value results in an output like this one:

          Code: Select all

          LocalDateTime=20160229084227.609000+060
          It can be seen that the value is YYYYMMDDHHmmss.microsecond±UTC offset in minutes. The format of this value is independent on language of operating system and current region and languages settings. The year is always the first with always 4 digits, the month is always the second with always 2 digits, the day is always the third with 2 digits, and so on without language specific date/time separators.

          Next we need to run in command prompt window for /? and set /? for help on command FOR needed to get the output of wmic loaded into an environment variable and for help on command SET to reformat this date/time value into the format we want in file name.

          So a simple batch file executed via a user tool for creating a backup of active file would be:

          Code: Select all

          @echo off
          for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS get LocalDateTime /format:value') do set "LocalDateTime=%%I"
          set "LocalDateTime=%LocalDateTime:~0,4%-%LocalDateTime:~4,2%-%LocalDateTime:~6,2%_%LocalDateTime:~8,2%-%LocalDateTime:~10,2%-%LocalDateTime:~12,2%"
          copy "%~1" "%~dpn1_%LocalDateTime%%~x1"
          
          This batch file with just four lines works in general.

          But does it work for every file backup operation?

          What else should we take into account for writing the batch file?
          • The batch file should do nothing if called without a parameter like when somebody double clicks on it.
          • The batch file should do nothing if called with a string which contains the wildcard characters * or ? as the batch file is designed for creating a copy of a single file and not a set of files matching a wildcard pattern.
          • The batch file should do nothing if called with a string which is not the name of an existing file.
          • The batch file should work also for on Windows unusual file names, but common on *nix systems like .htaccess.
          • The batch file should work also for a file with hidden or system attribute set opened in UltraEdit for editing which command COPY never copies (file not found).
          • And last it would be perhaps also good to get informed about an error on copying because of no read access permission on file to copy or no write access permission on file to create.
          So which batch file works really for all single file backup operations taking all requirements listed above also into account.

          Code: Select all

          @echo off
          setlocal EnableExtensions DisableDelayedExpansion
          rem Note: Remove both /V for copying large files faster without verification.
          
          rem Exit with error code 2 if batch file was called without a file name.
          if "%~1" == "" exit /B 2
          
          rem Exit with error code 3 if first parameter contains either * or ?
          rem because a single named file should be copied and not a set of files.
          for /F "delims=*?" %%I in ("#%~1#") do if not "%%I" == "#%~1#" exit /B 3
          
          rem Exit with error code 4 if first parameter does not
          rem specify name of an existing file (or directory).
          if not exist "%~1" exit /B 4
          
          rem Exit with error code 5 if first parameter is the name
          rem of an existing directory instead of an existing file.
          if exist "%~1\" exit /B 5
          
          rem Get local date and time in region and language independent format YYYYMMDDHHmmss.
          for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS get LocalDateTime /format:value') do set "LocalDateTime=%%I"
          
          rem Reformat the local date and time to format YYYY-MM-DD_HH-mm-ss.
          set "LocalDateTime=%LocalDateTime:~0,4%-%LocalDateTime:~4,2%-%LocalDateTime:~6,2%_%LocalDateTime:~8,2%-%LocalDateTime:~10,2%-%LocalDateTime:~12,2%"
          
          rem The Windows Command Processor interprets everything after last point
          rem as file extension even if there is nothing left like on hidden files
          rem on *nix systems starting with a point to be hidden like .htaccess
          rem This must be taken into account for the file copying task.
          
          if "%~n1" == "" (
              set "FileNameWithPath=%~dpx1"
              set "FileExtension="
          ) else (
              set "FileNameWithPath=%~dpn1"
              set "FileExtension=%~x1"
          )
          
          echo Copy "%~f1" to "%FileNameWithPath%_%LocalDateTime%%FileExtension%"
          
          rem Try to copy the file with standard command COPY with verification.
          copy /V /Y "%~f1" "%FileNameWithPath%_%LocalDateTime%%FileExtension%" >nul 2>&1
          
          rem Copying failed if exit code of COPY is greater or equal 1.
          if errorlevel 1 goto UseXcopy
          echo Success
          exit /B 0
          
          rem Command COPY can't be used for copying files with either hidden or
          rem system attribute set or if destination file exists already and has
          rem read-only attribute set. Therefore must use the command XCOPY as this
          rem command can copy also hidden and system files by using option /H,
          rem with keeping the attributes of copied file by using option /K,
          rem with overwriting also already existing file by using option /Y,
          rem even if destination file is read-only by using option /R,
          rem with verifying also successful copying of file by using option /V
          rem and with automatic continuation on failure by using option /C.
          
          rem But there is a real problem on using XCOPY for copying a single file:
          rem It prompts the user if the destination is a file or a directory if the
          rem destination file does not already exist. And this prompt depends on
          rem language of operating system.
          
          rem A hack is used to get the language dependent letter from prompt text
          rem without really copying any file. Command XCOPY is used to start copying
          rem the batch file itself to folder for temporary files with file extension
          rem being TMP for destination file. This results in a prompt by XCOPY if
          rem there is not already a file with that name in temporary files folder
          rem which is very unlikely. The handler of device NULL is used as an input
          rem handler for XCOPY resulting in breaking the copying process after the
          rem prompt was output by XCOPY 2 times. This output is processed in a FOR
          rem loop which is exited on first line starting with an opening parenthesis.
          rem This is the line on which second character defines the letter to use
          rem for specifying that destination is a file.
          
          rem The lines from the line below label UseXcopy up to and including line
          rem with label CopyFile can be removed completely if in line below label
          rem CopyFile the string %PromptAnswer% is replaced by the letter selecting
          rem file as answer on the machine on which this batch file is executed. On
          rem English Windows this would be letter F for file and letter D for Datei
          rem on German Windows.
          
          :UseXcopy
          del /F "%TEMP%\%~n0.tmp" 2>nul
          for /F %%I in ('%SystemRoot%\System32\xcopy.exe "%~f0" "%TEMP%\%~n0.tmp" ^<nul') do (
              set "PromptAnswer=%%I"
              setlocal EnableDelayedExpansion
              if "!PromptAnswer:~0,1!" == "(" set "PromptAnswer=!PromptAnswer:~1,1!" & goto CopyFile
              endlocal
          )
          echo ERROR: Failed to determine letter for answering prompt of XCOPY.
          exit /B 6
          
          rem The next issue to solve is that XCOPY is not reliable on error codes.
          rem For example if option /R would not be used and destination file has
          rem read-only attribute set, the single file copy fails with error message
          rem access denied written to STDERR stream, but the exit code of XCOPY is
          rem nevertheless 0 like on a successful copy. On other errors the exit code
          rem is correct like write access on existing destination file fails because
          rem the destination file is opened currently by an application with blocking
          rem shared access completely or allows just shared read for the file.
          
          rem So instead of evaluating the exit code, XCOPY is executed within a FOR
          rem loop to evaluate the number of copied files output on last line by XCOPY
          rem to STDOUT stream. The number of copied files is 1 on successful copy of
          rem the single file. Any other string (number 0) is interpreted as failed
          rem copy of the specified file. Output of copied files is suppressed by
          rem using option /Q of XCOPY.
          
          :CopyFile
          endlocal & set "PromptAnswer=%PromptAnswer%"
          for /F %%I in ('echo %PromptAnswer% ^| %SystemRoot%\System32\xcopy.exe "%~f1" "%FileNameWithPath%_%LocalDateTime%%FileExtension%" /C /H /K /Q /R /V /Y') do set "FilesCopied=%%I"
          if not "%FilesCopied%" == "1" (
              echo ERROR: Creating the backup failed, see error message above.
              exit /B 1
          )
          echo Success
          
          This batch code was tested on German Windows XP SP3 x86 and English Windows 7 SP1 x64.
          Best regards from an UC/UE/UES for Windows user from Austria

          Read more posts (-11 remaining)