Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: Making batch files foolproof  (Read 30144 times)

0 Members and 1 Guest are viewing this topic.

Dilbert

    Topic Starter
  • Moderator


  • Egghead

  • Welcome to ComputerHope!
  • Thanked: 44
    Making batch files foolproof
    « on: April 20, 2006, 12:15:54 AM »
    Question
    I want to distribute my batch file. How can I make sure users don't mess up my batch file?

    Answer
    It's a fact of life that if it is possible for some knucklehead to mess it up, he/she will. There are three main methods of making sure it doesn't get botched up: 1) Explain how it works before the user uses it, 2) make a help section of the batch, and 3) add protection code to ensure that the user cannot screw up.

    1. Create a readme file
    Include a readme to go with your batch file, explaining the syntax, its uses and limitations. This, however, is the least reliable method, as very few people actually read it, no matter how much you tell them to read it. However, some might, and anyone that reads your readme will benefit (assuming good info is in the readme and that it's easy to understand).

    2. Create a help section in your batch file

    It's as easy as creating a label and liberally using the ECHO command. You could make it so that the user would trigger the help section if they made a syntax error. This section would have ideally the same info as the readme. This is more likely to be seen; however, there will still be a chance of a logic error that will slip through even the best of syntax error catchers.

    3. Write code to catch errors in the usage of the batch file
    Though you should include at least #2 (it is also recommended that you include #1, it's not hard), this is the most sure-fire way of making sure the user cannot damage his/her system. However, it is also the most involved of the three procedures, and usually will double or triple the file length. This should not, however, concern you. What should concern you is how to write the code in a way that is effective and serves a good purpose.

    Let's take a look at an example. A user has an old version of the prompt not equipped with the move.com file that allows you to move files in DOS. This user (Average Joe) has to copy and delete the original. Mr. Joe wants his buddy to write a batch file that allows him to do what newer versions of the prompt can do. Let's say I am that buddy. The easy way out would be to write a batch file with two lines:

    Code: [Select]
    copy %1 %2
    del %1

    But this has its problems as well. What if Joe puts a directory name in, but not the filename! What happens? The file is copied to a file with the same name as the directory, and the original is erased! Well, no big deal, right? Just rename it to have a .txt or .jpg or whatever extension, right? However, this is inherently inefficient and causes grief as there is no message saying it was copied incorrectly, and it may take time for Joe to figure out he goofed.

    The best way to look at writing security for a batch file is to think of all the ways it can go wrong. So, I think about the different ways the copy command can go bad:

    • The source does not exist
    • The destination directory does not exist
    • The destination file already exists


    And of course:

    • User does not specify source/destination
    I. Source does not exist
    Easy enough to check with the following:

    Code: [Select]
    IF EXIST %1 GOTO DestCheck
    ECHO The file you wish to copy cannot be found. Make sure that you have
    ECHO not misspelled your file name and that it does exist.

    If the source file exists, it will go to a label marked DestCheck (covered next). The two ECHOs are skipped. However, if the file does not exist, the user is informed of this.

    II. Destination directory does not exist
    Not at all hard to do. I check the directory by attempting the copy the user wishes to make:

    Code: [Select]
    copy %1 %2\%1
    IF ERRORLEVEL 0 GOTO DeleteSource
    ECHO The directory you wish to copy to does not exist.
    ECHO Please pake sure you have not misspelled the directory name.

    This code block will attempt to copy the source to the directory, naming the file the same. (Note: This batch file does not support multiple file copies very well and your readme/help section should note this) If the errorlever (amount of errors) is equal to 0 (no errors), then go to the label that erases the source file; otherwise, notify the user there was an error.

    III. User attempts to copy to a file that already exists
    This is easy to check, and only slightly more complicated to solve. I find any pre-existing files with the block

    Code: [Select]
    IF EXIST %2\%1 GOTO Duplicate
    and the label "Duplicate" would have the following code:

    Code: [Select]
    ECHO The destination file already exists. The file name
    ECHO will be changed to prevent overwrite.

    III. User does not specify source/destination
    I simply check to see if %1 is empty with this:

    Code: [Select]
    IF %1=="" GOTO help
    IF %2="" GOTO help

    That's it! If %1 is empty, or if %2 is empty, go to the help section.
    « Last Edit: March 30, 2007, 03:14:40 AM by Dilbert »
    "The geek shall inherit the Earth."

    Dilbert

      Topic Starter
    • Moderator


    • Egghead

    • Welcome to ComputerHope!
    • Thanked: 44
      Re: QA0030 Making batch files foolproof
      « Reply #1 on: April 21, 2006, 04:49:08 PM »
      Putting it together
      Each block does next to nothing by itself. I have to assemble it in a way that makes sense. However, to do this requires me to declare two variables: %1 and %2 need to be given variables so the values can be modified.

      Code: [Select]
      @ECHO OFF
      IF "%1"=="" GOTO help
      REM - The below I switch makes the string comparison case insensitive
      IF /I "%1"=="help" GOTO help
      IF "%2"=="" GOTO help

      SET source=%1
      SET dest=%2
      SET error=

      IF EXIST %source% GOTO DuplicateCheck
      ECHO The source file does not exist. Please make sure the name is
      ECHO spelled correctly and the file exists.
      GOTO End

      :DuplicateCheck
      IF NOT EXIST %dest%\%source% GOTO CopyAttempt
      IF "%error%"=="1" GOTO RenameLayer2
      IF "%error%"=="2" GOTO Crash
      ECHO The destination file already exists. The name of the destination
      ECHO file will be altered to prevent overwrite. The extension of the
      ECHO file will be changed; you must re-enter the correct extension yourself.
      PAUSE
      SET source=xxyyzzabc.one
      SET error=1
      cls
      GOTO DuplicateCheck

      :RenameLayer2
      ECHO The name chosen for alteration already exists.
      ECHO A new name is being chosen.
      SET source=yxba.two
      set error=2
      GOTO DuplicateCheck

      :Crash
      cls
      ECHO The destination folder has maxed out on the number
      ECHO of renamed files it may contain. Please rename one
      ECHO or both of these files with the extension ".one" or
      ECHO ".two". Xmove will now close.
      GOTO End

      :CopyAttempt
      COPY %1 %dest%\%source%
      IF ERRORLEVEL 1 GOTO NoDirectory
      ECHO Copy completed successfully. Deleting source...
      GOTO DeleteSource

      :NoDirectory
      cls
      ECHO The directory you chose does not exist. Please
      ECHO make sure the directory you chose exists and
      ECHO that you did not misspell the name.
      GOTO End

      :DeleteSource
      DEL %1
      cls
      ECHO The move was completed successfully.
      GOTO End

      :help
      ECHO MOVE.BAT syntax:
      ECHO MOVE [source] [directory]
      ECHO.
      ECHO Note that this file does not support more than one file being copied at a time.
      ECHO It will work, but the resulting name will be "wrong". Also note that if you try
      ECHO to move to a file that exists, the batch will attempt to change the name of
      ECHO the file. It will not allow you to copy to a directory that does not exist.
      GOTO End

      :End

      And I was done, having a perfectly good replacement for move.com.
       
      Phew! That's one long code for a simple concept of moving files. However, it makes sure that there is no possible way that the user can cause himself headaches (although renaming the .one and .two files takes a little work).
       
      Another important notice
      As you may know, batch files must be in a folder included in the PATH variable in order to work outside of that folder. A folder that is always in the PATH variable is System32; make sure the user knows about this, either in your readme, in the place where the file is attached/hosted, or in the help section (since it can run in the folder it's in without modifying the PATH variable).This is just one example. The general rule for other batch files is to think of every possible way the user can be a complete bonehead, then take steps to prevent it. This concept applies to all programming, from batch to C++ to FORTRAN and even Assembler.
       
      For any out there who use a version of the prompt that doesn't have move.bat, or if you want to use this batch for fun, I have attached the batch file. If you read what I wrote in the help section, there is no need for a readme.

      This post and attachment has been edited 4 times. Reasons: code error fixed; code error fixed; added cls to code; prevented infinite loop and fixed abnormal screen clearing

      [old attachment deleted by admin]
      « Last Edit: March 28, 2007, 05:35:09 PM by Dilbert »
      "The geek shall inherit the Earth."