The Code Cave

April 6, 2006

How to: Creating a unique temporary file and determining the working drive and path

Filed under: Batch — Brian @ 11:05 am

This is a demonstration of how to use a TempFile in a .BAT or .CMD file. The goal of this example is to determine the relative path of the current working directory and assign it to a variable.

Concepts Demonstrated:


  • Generating a unique file names

  • Creating a temp file, using the Windows Naming convetion, and deleting it when done

  • Calling support subroutines in a batch file

  • Using GOTO :EOF to end exit a subroutine but not the batch file

  • Use of the command line “FOR” routine

  • Using Variables with “for /F”

  • How to get the current directory

  • Verbose and Quiet modes for a batch file

Temporary files are incredibly useful in batch files. When used in combination with a “For” loop, you can accomplish some amazing stuff from the command line.

In this example we assign a new file name to the TEMPORARY_FILE variable and then export the current working path to that file by echoing cd environment variable to it:

call :GETTEMPNAME
echo %cd%>%TEMPORARY_FILE%

Once our temp file has contents, the For routine can be used to parse each line and execute a command with the result. So, we use the For command to divide the working directory, lets say it is “C:\WorkingDir” into several peices (aka tokens):

FOR /F “tokens=1* delims=:” %%G IN (%TEMPORARY_FILE%) DO set RelativePath=%%H

Literaly we are telling it to break the line up at every colon ( : ), and to assign the first token to the variable %G. The asterisk (*) indicates that each token after that should be assigned to a new variable letter (H,I,J, and etc.). In our example, our %H will contain “\WorkingDir”.

“For /F” is really most usefull with larger files containing multiple lines. Since our file contains only one line with two tokens, the process stops there but you could, for example, parse all the names of files in a directory (dir *.xyz /b > %TEMPORARY_FILE%), or the contents of a registry key exported to that file using (REG QUERY [...] > %TEMPORARY_FILE%). I’ve used both of these methods in the past to do some really neat things that might have otherwise involved creating a custom executible. One advantage of doing it from teh command line is that it keeps the registry clean of all the garbage left behind by Windows anytime you run an exe.

Oh!

Something that is not often emphasized in “For /F” documentation is that it can parse variables as well as files. This could greatly optimize this example. Instead of parsing our file, we would simply put our %CD variable in quotes and call:

FOR /F “tokens=1* delims=:” %%G IN (”%CD%”) DO set RelativePath=%%H

We will get exactly the same results and can cut our batch file size in half! Of course, then we wouldn’t have a good example of temp file usage would we? So, we will do it the hard way.

Thus:

http://www.thecodecave.com/downloads/batch/GetRelativePath.bat

DOS:
  1. @Echo Off
  2. ::*************************************************************************
  3. :: This is a demonstration of TempFile usage, Batch Subroutines, using
  4. :: the FOR loop to parse parameters, Goto :EOF, using parameters to
  5. :: control the Verbose or Quiet execution of a batch routine, getting the
  6. :: local directory from an environment variables and the use of long
  7. :: comments in a batch file.
  8. ::
  9. :: Usage:
  10. ::   GetRelativePath          <– Shows the essential output
  11. ::   GetRelativePath Verbose  <– Shows all of the work
  12. ::
  13. :: This routine is pretty simple.  It gets a guaranteed unique temporary
  14. :: filename uses it and then puts the current path in that file. It then
  15. :: use the For command to break that path into peices at the colon and
  16. :: put the second chunk in an environment variable.  That all could be
  17. :: done with the for loop parsing the local variable, but then we
  18. :: wouldn’t have an example of using a temp file would we?
  19. ::
  20. :: Original Author - Brian Layman
  21. ::
  22. :: Created       - 01/APR/2006
  23. :: Last Modified - 01/APR/2006
  24. :: Contributors: (Put your name & Initials at the top)
  25. ::   Brian Layman - BL - http://www.TheCodeCave.com
  26. ::
  27. ::
  28. :: History:
  29. ::   01/APR/2006 - BL - Created
  30. ::
  31. :: License - If this helps you - Great! Use it, modify it share it.
  32. ::
  33. :: Indemnity -
  34. ::    Use this batch file at your own risk.  I’m only calling built-in Windows
  35. ::    commands, but if a typo or service pack change affects what this routine
  36. ::    does, it is not my fault.  In fact, you should just stop right now and
  37. ::    not run this file.  For if it causes blue smoke to be emitted from your
  38. ::    network card, if it resets your home site to HowToKillMyBoss.com, or if
  39. ::    it makes your sister break up with her lawyer boyfriend and start dating
  40. ::    a caver, it is not my fault.  (Actually that last one might be an
  41. ::    improvement, but it is still not my fault.)
  42. ::
  43. :: Donations - If this batch file really helps you out, feel free to make a $5
  44. ::    (US) donation via Paypal to Brian@TheCodeCave.com or just send a Thank
  45. ::    You via email to that address and include your country of origin.
  46. :: ::*************************************************************************
  47.  
  48. :: *************************************************************************
  49. :VerboseCheck
  50. ::  Check for the Verbose password.
  51. :: *************************************************************************
  52. :: Put a bracket around the %1 to trap for empty values and to allow the
  53. :: string comparison to work
  54. if NOT [%1] == [Verbose] GOTO :TheWorks
  55. echo On
  56. :: *************************************************************************
  57.  
  58. :: *************************************************************************
  59. :TheWarning
  60. ::
  61. ::  Normally a Quiet variable would display some info about the program
  62. ::  and also allow several ways to abort an accidental launch, but this
  63. ::  example uses a verbose command to make it show all of the work.
  64. ::
  65. :: *************************************************************************
  66. Echo Maximum Verbosity.
  67. Echo Hit Ctrl+Break now to stop here or just
  68. @pause
  69.  
  70. :: *************************************************************************
  71. :TheWorks
  72. ::
  73. ::  Let the fun begin!
  74. ::
  75. :: *************************************************************************
  76. if NOT [%1] == [Verbose] @Echo off
  77. Echo Generating Temp name
  78.  
  79.  
  80.  
  81. if [%1] == [Verbose] Echo *************************************************************************
  82. call :GETTEMPNAME
  83. if [%1] == [Verbose] Echo *************************************************************************
  84. Echo.
  85. Echo Temp name is %TEMPORARY_FILE%
  86. Echo.
  87. Echo Current Directory is %cd%
  88. Echo.
  89. Echo The next process strips the drive designation off and stores the new value
  90.  
  91. :: Strip off the Drive letter for the server path
  92. :: This involves some fancy footwork with a temp file and a For statement.
  93. call :GETTEMPNAME
  94. if [%1] == [Verbose] Echo *************************************************************************
  95. :: Send the current path out to a temp file so that it can be used with FOR /F statements
  96. echo %cd%>%TEMPORARY_FILE%
  97. FOR /F "tokens=1* delims=:" %%G IN (%TEMPORARY_FILE%) DO set RelativePath=%%H
  98.  
  99. if [%1] == [Verbose] Echo *************************************************************************
  100. Echo.
  101. Echo The relative path is %RelativePath%
  102.  
  103.  
  104. :: *************************************************************************
  105. :TheEnd
  106. ::
  107. ::  So long and thanks for all the fish!
  108. ::
  109. :: *************************************************************************
  110. Echo.
  111. pause
  112. GOTO :EOF
  113.  
  114. Echo.
  115. :: *************************************************************************
  116. ::  Support procedures
  117. ::
  118. ::  These routines are called with a CALL directive and the GOTO :EOF
  119. ::  terminates that CALL but does not terminate the entire running of the
  120. ::  batch file.
  121. :: *************************************************************************
  122.  
  123. :: *************************************************************************
  124. ::  GETTEMPNAME procedure
  125. ::  Create a temporary file name guaranteeing the file doesn’t exist
  126. ::
  127. ::  Returns:      TEMPORARY_FILE=Temporary file name
  128. ::
  129. :: *************************************************************************
  130. :GETTEMPNAME
  131.       if not defined _NEXTTEMP set /a _NEXTTEMP=1
  132.       :GETTEMPNAMELOOP
  133.          if defined TEMP (
  134.             (set TEMPORARY_FILE=%TEMP%)
  135.          ) else if defined TMP (
  136.             (set TEMPORARY_FILE=%TMP%)
  137.          ) else (set TEMPORARY_FILE=%SystemRoot%)
  138.          set /a _NEXTTEMP=_NEXTTEMP * 214013 + 2531011
  139.          set /a _T1=_NEXTTEMP ^>^> 16 ^& 0×7FFF
  140.          set TEMPORARY_FILE=%TEMPORARY_FILE%\~SH%_T1%.tmp
  141.          if exist "%TEMPORARY_FILE%" GOTO :GETTEMPNAMELOOP
  142.       set _T1=
  143. GOTO :EOF
  144. :: *************************************************************************

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress