Searching user, System for built-in cmds / 'where' cmd for XP

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Searching user, System for built-in cmds / 'where' cmd for XP

#1 Post by thefeduke » 06 Jul 2015 01:23

I am editing this post to clarify the topic as it has developed.
Here I am presenting a couple of tools dealing with displaying the access to DOS programs in light of the operating system search order.
Questions that have or may be answered here may be of some educational interest to those new to the topic.


  • IsItDOS.bat The code has been moved to this post. This utility accepts a string and attempts to determine if such a command exists, its location, and classifies it as a command, System or built-in DOS command.
  • PathFinder.batThis utility does a more comprehensive search to list all instances in precedence along the actual or proposed search path as well as invoking IsItDOS to add system if it applies. The code below has been replaced with the latest version.
  • These routines have been tested on Win XP and provide a limited (wildcards are missing) 'where' command which does not exist on XP. There is an option to turn off 'How am I doing' messages to simulate 'where' output.

Code: Select all

:IsitDOS cmd         -- Determine if a string is a DOS system command
::                   -- cmd   [in]  - Command name with no extension
::Returns            -- errorlevel: 0 if DOS builtin or system command, 1 if not
::
@Echo Off &SetLOCAL EnableDelayedExpansion &Rem.and keep environment uncluttered.
If "%~1"=="" Echo.&Echo.IsItDOS [-h][/?] CmdName [-h][/?]
If "%~1"=="" Echo.Command name is required. Terminating [rc=1] . . .&Exit /B 1
If /I "%~1"=="-h" Echo.&Echo.Syntax: IsItDOS [-h][/?] CmdName [-h][/?] - Terminating [rc=01] . . .&Exit /B 1
If /I "%~2"=="-h" Echo.&Echo.Syntax: IsItDOS [-h][/?] CmdName [-h][/?] - Terminating [rc=01] . . .&Exit /B 1
If "%~1"=="/?" Echo.&Echo.Determine if a string is a DOS builtin or System command.
If "%~1"=="/?" Echo.&Echo.IsItDOS [-h][/?] CmdName [-h][/?] - Terminating [rc=01] . . .&Exit /B 1
If "%~2"=="/?" Echo.&Echo.IsItDOS [-h][/?] CmdName [-h][/?] - Terminating [rc=01] . . .&Exit /B 1
    Rem.DOS Testing Environment '0' easy to find temporary folder
    Set "tmpd=%TEMP%\'0'"
    If Not Exist "%tmpd%" MkDir "%tmpd%"
::  Following command terminates batch script if exists and may produce bad output
::  >%tmpd%\%~n0.txt %~1 /? 2>nul
::  Above command is coaxed to run on its own so as not to end this one
    >"%tmpd%\%~n0.cmd" (
        Echo.@Echo Off
        Echo.SetLOCAL EnableEXTENSIONS
        Echo.%~1 /?
    )
    2>nul Call "%tmpd%\%~n0.cmd" >"%tmpd%\%~n0.txt"
    @Echo Off&Rem.Previous Call command leaves Echo On
    2>nul (
        FOR /F "UseBackQ tokens=1-4,5* " %%i in (`DIR "%tmpd%\%~n0.txt" /A:-S-d /-C /S`) do (
            IF "File(s)"=="%%j" set resultuse=%%k
        )
    )
    If "%resultuse%"=="" (Set "resultuse=0")
    If %resultuse%==0 (
        Set "IsItDOSrc=1"
    )
    >"%tmpd%\%~n0_Help.cmd" (
        Echo.@Echo Off
        Echo.SetLOCAL EnableEXTENSIONS
        Echo.HELP
    )
    2>nul Call "%tmpd%\%~n0_Help.cmd" >"%tmpd%\%~n0_Help.txt"
    For /F %%H in ('findstr /I /L /C:"%~1" "%tmpd%\%~n0_Help.txt"') do (
        If /I .%%H EQU .%~1 Set "Helped=%%H"
    )
    If /I .%Helped% EQU .%~1 (
        If /I "%~2" NEQ "-q" (Echo.
            Echo.Crosschecking with general System HELP for '!Helped!' was positive.
        )
        Set "resultuse=1"
    )
    If %resultuse%==0 (
        If /I "%~2" NEQ "-q" (
            Echo.
            Echo.'%~1' produced no HELP output, failing a DOS builtin command check.
        )
        Echo.
        Echo.'%~1' appears NOT to be a DOS builtin or System command.
    ) Else (
        If /I "%~2" NEQ "-q" (
            Echo.
            Echo.'%~1' responds during DOS builtin command check for any help output.
        )
        If Defined Helped (
            Set "IsItDOSrc=0"
        ) Else (
            set /a counter=1
            Set "IsItDOSrc=1"
            FOR /F "usebackq tokens=1* " %%i in ("%tmpd%\%~n0.txt") do (
                set /a counter+=1
                IF /I "%~1"=="%%i" (
                    IF "!counter!" LEQ "4" Set "IsItDOSrc=0"
                )
                IF "!counter!" GEQ "5" GoTo foundDOS
            )
        )
:FoundDOS
        If "!IsItDOSrc!"=="1" Echo.'%~1' Appears NOT to be a DOS builtin command.
    )
    SET ComSpecDir=%ComSpec:\cmd.exe=%
    Call :AnyPath %~1
    If "%IsItDOSrc%"=="0" (
        If Exist %ComSpecDir%\%~1.exe (
            Echo.'%~1.exe' is a DOS system command in '%ComSpecDir%'.
            If Defined AnyName (
                If /I  %ComSpecDir%\%~1.exe NEQ !AnyName! (
                    Echo.and has been pre-empted by '!LongName!'.
                )
            )
        ) Else (
            If Exist %ComSpecDir%\%~1.com (
                Echo.'%~1.com' is a DOS system command in '%ComSpecDir%'.
                If Defined AnyName (
                    If /I  %ComSpecDir%\%~1.com NEQ !AnyName! (
                        Echo.and has been pre-empted by '!LongName!'.
                    )
                )
            ) Else (
                If Defined AnyName (
                    Set "IsItDOSrc=1"
                    If /I "%~2" NEQ "-q" (
                        Echo.'%~1' produced Help output in a format consistent with a DOS command.
                    )
                    If Defined Helped (
                        Set "IsItDOSrc=0"
                        Echo.'%~1' appears to be built into the DOS command interpreter.
                        Echo.and has been pre-empted by '!LongName!'.
                    ) Else (
                        Echo.'%~1' appears NOT to be a DOS builtin or System command.
                        Echo.but was found as '!LongName!'.
                    )
                ) Else (
                    Echo.'%~1' appears to be built into the DOS command interpreter.
                )
            )
            rem.
        )
    ) Else (
        If Defined AnyName Echo.first encountered as !LongName!.
    )
    set Name=
    set AnyName=
    set LongName=
    Del "%tmpd%\%~n0.cmd"
    Del "%tmpd%\%~n0.txt"
    Del "%tmpd%\%~n0_Help.cmd"
    Del "%tmpd%\%~n0_Help.txt"
    Exit /B %IsItDOSrc%

:AnyPath
@echo off
set Name=%~1
set AnyName=
:: MiniMax http://www.dostips.com/forum/viewtopic.php?p=44278#p44278
for %%X in (%PATHEXT%) do @for %%F in (%Name%%%X) do (
    @if exist %%~dp$PATH:F\%%F (
        Set AnyName=%%~dp$PATH:F%%F
        Set LongName=%%~dp$PATH:F%%F in the search path
    )
)
SET NAMEEXT=!PATHEXT:.=%1.!
:: Aacini http://www.dostips.com/forum/viewtopic.php?p=44266#p44266
FOR %%N IN (%NameEXT%) DO IF EXIST %%N (
    Set AnyName=%CD%\%%N
    Set LongName=%CD%\%%N in the current directory
)
If Defined AnyName (
    Exit /B 0
) Else (
    Exit /B 1
)

Update PathFinder code follows unedited narrative below:
My disorganization in using program folders as current directories and in the path has aggravated me when poor batch script name choices usurp existing ones causing surprising results. Explicit calls cause fewer such problems but make changes a real chore.

I hope that some of the contributors from which I draw much inspiration here might check my code to verify that I have correctly interpreted how the system chooses exactly which file will run from a call statement.

So I offer the following code that I use to see if a command name is free or already in use and perhaps hiding other commands behind it in the search order.

Code: Select all

:PathFinder  cmd found Fnx road exts
@goto :ENDofHELP
::PathFinder cmd found Fnx road exts
::                 -- Determine if (and from where) a command would run
::                 -- cmd   [in,opt]  - Command name (extension optional)
::                 -- Found [out,opt] - 1st fully qualified execution folder
::                 -- Fnx   [out]     - first execution filename
::                 -- road  [in,opt]  - treat as path
::                 -- exts  [in,opt]  - treat as pathext
::                 -- console output shows commands blocked by first one
::                 -- errorlevel 0 if found or 1 if command not found
::Dependencies: IsItDOS function to check for DOS builtin command
::Acknowledge: Help modelled after JREPL.BAT by Dave Benham, originally posted at
::             http://www.dostips.com/forum/viewtopic.php?f=3&t=6044
::
::PathFinder.BAT version 2.2 by John Andrejsons
::
::  Release History:
::    2015-12-07 v2.2: Added /T to control output
::    2015-09-15 v2.1: Corrected to reverse PATH and PATHEXT search order
::    2014-08-30 v2.0: Added HELP and option for output emulationg WHERE command
::    2015-08-15 v1.2: Added paths loop to really find more than just first one
::    2015-08-03 v1.1: Added path and pathext options - fixed so rtrim not needed
::    2015-07-15 v1.0: Post to http://www.dostips.com/forum/viewtopic.php?p=41940
::
::============ Documentation ===========
::
:::
:::  Lists path components where a command is found and by what filename.ext
:::
:::PathFinder [ /T ] cmd [found] [Fnx] [road] [exts]
:::
:::           [ -H | /? | /?? | /?Version ]
:::
:::  /T       - Reduces message traffic to appear more like
:::             the output of option /T of the 'where' command.
:::
:::  cmd     - required name of command with or without extension
:::
:::  NOTE:   * The following four arguments, although optional,
:::            are all positional and need a "" placeholder for
:::            missing arguments to postion a following selection.
:::
:::  found   - name of symbolic variable to receive the fully qualified
:::            name of the command that would be executed.
:::
:::  Fnx     - name of symbolic variable to receive name of command
:::            including extension that would be executed.
:::
:::  road    - string in the format of the PATH variable
:::            to be used as a hypothetical search path.
:::
:::  exts    - string in the format of the PATHEXT variable
:::            to be used as an override during the search.
:::
:::  This command performs a search of the path using PATHEXT order
:::  and offers limited function similar to the DOS builtin command 'WHERE'
:::  but works in the Windows XP environment which has no such command.
:::
:::  In addition a check is made for DOS builtin command status
:::  based on help output format criteria in response to the /? parameter.
:::
:::  If a symbolic variable 'Mute' is set to the value Rem. (Set "Mute=Rem."),
:::  the output is customized to appear like that of the 'WHERE' builtin command
:::  This can be activated by /T as the first argument which
:::  also shifts the remaining arguments to their expectd places.
:::
:::  HELP is available by supplying a single argument:
:::
:::    [ /? | -H ] - Writes formal help documentation to stdout.
:::
:::      /??       - Same as /? except uses MORE for pagination.
:::                  This includes all '::' commentary.
:::
:::      /?VERSION - Writes the PathFinder version number to stdout.
:::
:::  Return Codes:
:::
:::      0 = At least one instance of the specified command was found
:::
:::      1 = Command not found
:::          or HELP was requested
:::
:::  PathFinder.BAT was written by John Andrejsons, and originally posted at
:::  http://www.dostips.com/forum/viewtopic.php?p=41940
:::

============= :ENDofHELP portion ===========

============= :Batch portion follows =======
    @Echo Off &SetLOCAL EnableDelayedExpansion &Rem.Keep environment vars uncluttered.

    If "%~1"=="" (
:False  rem.Return False by setting %errorlevel% to 1.
        Set=2>nul
        Echo.&Echo.[rc=!ErrorLevel!] from checking passed variables to '%~nx0'
        Echo.HELP is available using any of these parameters: -H, /?, /??.
        Echo.Error^^! Required command name not supplied. Terminating [rc=1] . . .
        Exit /B 1
    )
    if "%~1" equ "/?" (
        For /f "tokens=* delims=:" %%A in ('findstr "^:::" "%~f0"') do @echo(%%A
        Exit /b 1
    ) Else if /I "%~1" equ "-H" 2>nul (
        For /f "tokens=* delims=:" %%A in ('findstr "^:::" "%~f0"') do @echo(%%A
        Exit /b 1
    ) Else if /i "%~1" equ "/?Syntax" (
        For /f "tokens=* delims=:" %%A in ('findstr "^:::Syntax" "%~f0"') do @echo(%%A
        Exit /b 1
    ) Else if /i "%~1" equ "/?version" (Echo.
        For /f "tokens=* delims=:" %%A in ('findstr "^::PathFinder\.BAT" "%~f0"') do @echo(%%A
        Exit /b 1
    ) Else if "%~1" equ "/??" 2>nul (
        (For /f "tokens=* delims=:" %%A in ('findstr "^::" "%~f0"') do @echo(%%A)|more /e
        Exit /b 1
    ) Else if /I "%~1" equ "/T" (
        Set "mute=Rem."
        Shift /1
    )

    IF Exist "%~nx1" (%Mute%Echo. &%Mute%Echo.Filename "%~1" found ASIS in Current Directory %cd%
        %Mute%Echo.and takes precedence before any search path folders.
        Set "Found=%cd%\%~1"&Set "Fnx=%~1"
    )

    Set "tmpd=%TEMP%\'0'"
    If Not Exist "%tmpd%" MkDir "%tmpd%"

    1>"%tmpd%\PthList.bat" Echo.    @Echo OfF
    Set "RoadPth=%path%"
    If "%~4"=="" (
        %Mute%Echo.&%Mute%Echo.Optional path alternative not specified . . .
    ) Else (%Mute%Echo.
        >>"%tmpd%\PthList.bat" Echo.    If Exist "%tmpd%\PthList.txt" Erase "%tmpd%\PthList.txt"
        >>"%tmpd%\PthList.bat" Echo.    Set "roadPth=%%%~4%%"
        >>"%tmpd%\PthList.bat" Echo.    %Mute%Echo.Optional PATH=%%%~4%%
    )
    Call "%tmpd%\PthList.bat"

    1>"%tmpd%\ExtList.bat" Echo.    @Echo OfF
    Set Roadext=%pathext%
    If "%~5"=="" (
        %Mute%Echo.&%Mute%Echo.Optional pathext alternative not specified . . .
    ) Else (%Mute%Echo.
        >>"%tmpd%\ExtList.bat" Echo.    If Exist "%tmpd%\ExtList.txt" Erase "%tmpd%\ExtList.txt"
        >>"%tmpd%\ExtList.bat" Echo.    Set "roadext=%%%~5%%"
        >>"%tmpd%\ExtList.bat" Echo.    %Mute%Echo.Optional PATHEXT=%%%~5%%
    )
    Call "%tmpd%\ExtList.bat"

    SET Extensions=^>"%tmpd%\ExtsList.txt" Echo.!RoadExt:;=^&^>^>"%tmpd%\ExtsList.txt" Echo.!
    %Extensions%
    Call:QualFetch "%~1"
    If Defined Found GoTo Found &Rem.Bypass rolling through PATH

    SET Paths=^>"%tmpd%\PathList.txt" Echo.%~1 !path:;=^&^>^>"%tmpd%\PathList.txt" Echo.%~1 !
    %Paths%

    %Mute%Echo.&%Mute%Echo.Searching current directory for command "%~n1" . . .
    For /F "UseBackQ Tokens=1* delims=" %%A in ("%tmpd%\ExtsList.txt") Do (
        If Exist "%~1%%A" (Set "FetchFile=%~1%%A"
            FOR /F "UseBackQ tokens=1-4,5* " %%a in (`DIR "%~1%%A" /A:-S-d /-C`) do (
                IF /I "%~1%%A"=="%%e" (
                    If Defined Mute Echo.%%d %%a %%b %%c %CD%\%~1%%A
                    %Mute%Set <nul /P =Found={
                    %Mute%Set <nul /P =%CD%\%~1%%A
                    %Mute%Set <nul /P =}
                )
            )
            %Mute%Echo.&%Mute%Echo.File "!FetchFile!" found in Current Directory "%cd%"
            If Not Defined found (
                %Mute%Echo.and takes precedence before any search path folders.
                Set "Found=%cd%\!FetchFile!" & Set "Fnx=!FetchFile!"
            )
        )
    )
    %Mute%Echo.&%Mute%Echo.Searching for command "%~n1" in path folders . . .
    For /F "UseBackQ Tokens=1* delims=" %%I in ("%tmpd%\PathList.txt") do (
        Set "FetchFile=%%I"
        Set "FetchPath=%%J \"
        Set "FetchPath=!FetchPath:\ \=!"
        Set "FetchPath=!FetchPath: \=!"
        Call:QualFetch !FetchFile! !FetchPath!
    )
:Found
    If Defined Found Echo.
    Call IsItDOS %~n1 -q
    (EndLOCAL &Rem.Return Values
        Set found=%Found%
        If "%~2" NEQ "" (SET %~2=%Found%) ELSE (
            If Defined Found (
                %Mute%Echo.&%Mute%Echo.First in call sequence: '%Found%'
            )
        )
        If "%~3" NEQ "" (SET %~3=%Fnx%)
        If Defined Found (
            Set "Found="
            %Mute%Echo.&Exit /B 0
        ) Else (
            Echo.&Echo.'%~1' was not found in a call path sequence folder.
            %mute%Echo.&Exit /B 1
        )
    )

:QualFetch
    For /F "UseBackQ Tokens=1* delims=" %%I in ("%tmpd%\ExtsList.txt") do (
        If Exist "%~2\%~1%%I" (
            %Mute%Set <nul /P =Found={
            FOR /F "UseBackQ tokens=1-4,5* " %%a in (`DIR "%~2\%~1%%I" /A:-S-d /-C`) do (
                IF /I "%~1%%I"=="%%e" (
                    If Defined Mute Set <nul /P =%%d %%a %%b %%c %~2\%~1%%I
                    If Defined Mute Echo.
                    %Mute%Set <nul /P =%~2\%~1%%I
                )
            )
            %Mute%Set <nul /P =}
            %Mute%Echo.
            If Not Defined found (Set "Found=%~2\%~1%%I" & Set "Fnx=%~1%%I")
        )
    )
    Exit /B


The following could be useful in trying it out.

Code: Select all

@Echo Off
If "%~1"=="" Echo.&Echo.Command name is required. Terminating (rc=1) . . .&Exit /B 1
    Call PathFinder "%~1" findpath findfile
    If %errorlevel%==0 (
        Echo.Resulting variables are:
        Set Find
    ) Else (
        Echo.[rc=%errorlevel%] No results for "%~1" search.
    )
    Echo.&Echo.Or with no saving of names:
    Call PathFinder "%~1"
    Exit /B


My XP system is inoperable for a while so I have only tested it on Windows 7.
[Edited: system working and code tested on XP.]
I welcome critiques or corrections (particularly in method).

John A.
Last edited by thefeduke on 09 Dec 2015 03:23, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Call command - accidental path interference

#2 Post by foxidrive » 06 Jul 2015 07:03

thefeduke wrote:My disorganization in using program folders as current directories and in the path has aggravated me when poor batch script name choices usurp existing ones causing surprising results. Explicit calls cause fewer such problems but make changes a real chore.


I'm trying to understand how your system is not-organised and how it affects your choice of script name.
Do you have batch files strewn all throughout your folder structure?

Just wondering.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Call command - accidental path interference

#3 Post by thefeduke » 06 Jul 2015 11:24

foxidrive:
Do you have batch files strewn all throughout your folder structure?


I tend to start more things than I finish. In a previous life I was a mainframe dinosaur and used DOS 1.1 on the original IBM PC using Multi-Plan later Lotus123 in the 80's. Assembler oriented colleagues created some really handy 16-bit programs in those days that I still use. I came to the USA with my PS/1 and brother-in-law's cast-off clone with Windows 95 and some soft and hard floppies. About 3 years ago my Vista laptop fried and I used the PCs at my library for 2 hours a day until my friend replaced his XP system suffering from the chronic Blue Screen death and I rebuilt it from starter disks and began my PC batch revival hobby. Everything on the cheap in my retirement as I built a batch testing environment to backup his Windows 8 artwork images. (He tended to go back to zero whenever his system hiccuped.)

Then I DISCOVERED DOSTips!

In my joy of doings things better while maintaining and improving a flash-drive for him, I have old and new libraries of programs, unchanged and adapted DOStips examples, subroutines, functions, a Java self-education environment and isolated proprietary code. I am in the midst of initializing various environments depending on which removable media I plug into USB ports on this and my newly acquired $104 refurbished Windows 7 system.

"Don't fix it if it's not broke" is boring and I have a lot of time on my hands.

For example I do not like what happens if you type EDIT on a pristine system. Editors have various cut-and-paste capabilities, appearance, functionality, line or word orientation, multi-windowing capabilities and familiarity that might be best suited to a particular environment. I might prefer the EDIT command to mean different things in various path structures. This pathfinder lets me see what I am getting and what I may be hiding.

Hey Foxi, you asked. Everything is under construction.
John A.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Call command - accidental path interference

#4 Post by foxidrive » 06 Jul 2015 11:40

I admire your obvious enjoyment, and helping friends.

I'm not sure that typing 'edit' and having something else happen is a good path to take,
as you seem to be saying that you'd like to replace default system commands.

That can lead to different kinds of file system damage - if you replace a system command and
then run a script written by someone else which uses that system command.

But having said that: placing your batch file folder earlier on the PATH will allow you to store your batch files in a single place and launch them from anywhere else. It also allows you to replace system commands.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Call command - accidental path interference

#5 Post by thefeduke » 06 Jul 2015 14:54

Thank you Foxidrive:
placing your batch file folder earlier on the PATH will allow you to store your batch files in a single place and launch them from anywhere else. It also allows you to replace system commands.

The converse of this statement is more the purpose of PathFinder.bat .
I am not intimate with the detailed contents of the system path and any changes that were introduced by installing some product, nor do I want to be.

Scenario: Let's develop a new batch script called NewStuff.bat in an arbitrary Current Directory. At some point I would promote this file to a directory in my Path. This is where the PathFinder comes in to tell me if I am indeed interfering with anything else that has already used the name NewStuff with any valid extension in the path to avoid just such a replacement.

So, back to the purpose: theory and application. Do the mechanics of this code reflect the actual DOS search strategy correctly enough to be useful? I welcome your experience.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Call command - accidental path interference

#6 Post by foxidrive » 06 Jul 2015 22:28

thefeduke wrote:The converse of this statement is more the purpose of PathFinder.bat .
I am not intimate with the detailed contents of the system path and any changes that were introduced by installing some product, nor do I want to be.


There is no need to know anything about any other application that is using the PATH variable.

Where you see something like this in the master Windows environment in control panel (for your username), system, advanced settings someplace:


C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;


Add this bit at the start - and you have two folders on the path for you to consolidate all your batch file and utility programs into, and will be used in preference to any built in command on the path.


c:\files\bat;c:\files\util;
C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;


Take note that Windows has other methods to determine programs that respond to a command line.

Scenario: Let's develop a new batch script called NewStuff.bat in an arbitrary Current Directory. At some point I would promote this file to a directory in my Path. This is where the PathFinder comes in to tell me if I am indeed interfering with anything else that has already used the name NewStuff with any valid extension in the path to avoid just such a replacement.


There's a straight forward way to find out if a name is already used, such as blueberry-pie.bat
Just open a cmd prompt and type blueberry-pie /? and see if you get an error message
'blueberry-pie' is not recognized as an internal or external command, operable program or batch file.
and you know it's safe.

So, back to the purpose: theory and application. Do the mechanics of this code reflect the actual DOS search strategy correctly enough to be useful? I welcome your experience.


One of the peeps may have the brain power to run an eye over your code - I will have a look tomorrow if nobody else chimes in.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Call command - accidental path interference

#7 Post by thefeduke » 17 Jul 2015 02:36

Foxidrive:
Add this bit at the start - and you have two folders on the path for you to consolidate all your batch file and utility programs into, and will be used in preference to any built in command on the path.
c:\files\bat;c:\files\util;

Here is how I modified my previous approach to mix my old with new projects:

Code: Select all

    SET 'Rdrv=%~d0
    SET mediacdr=%~p0\
    SET 'Rdir=%mediacdr:\\=%
    SET mediacdr=
    IF Not DEFINED 'Adir (
        SET 'Adir=\'pgms\AUO
    )
    IF Not DEFINED 'Fdir (
        SET 'Fdir=\'pgms\Functions
    )
    SET 'appendedPATH=%'rdrv%%'Fdir%;%'rdrv%%'Adir%;%'rdrv%%'Rdir%
    SET 'savedPATH=%PATH%

:: from called code
    Set "dd=%~d0"
    Set "cmdd=%dd%\Programs
    Set "'addedPATH=%cmdd%\Functions"
:: back again

    PATH %'addedPATH%;%'savedPATH%;%'appendedPATH%

The path can then easily be restored or altered using the above three variables.
Inspiration from Foxidrive:
Just open a cmd prompt and type blueberry-pie /? and see if you get an error message

My PathFinder.bat from above just picks up system commands in the output but does not flag them and completely misses those hidden within CMD. As I was working on applying your straight forward method, a recent forum post mentioned the WHERE command, that, by just being, shows that someone saw a need for the function. My XP system is still sidelined, so I cannot tell if the was a where in XP. Would someone please let me know?

I am determined to add the following code to PathFinder anyway. This routine stands on its own:

Code: Select all

:IsitDOS cmd         -- Determine if a string is a DOS system command
:: this code has been moved to the first post of this topic

I'd appreciate any test results on XP.

Thanks, John A.
Last edited by thefeduke on 09 Dec 2015 03:30, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Call command - accidental path interference

#8 Post by foxidrive » 05 Dec 2015 02:12

One of the peeps may have the brain power to run an eye over your code - I will have a look tomorrow if nobody else chimes in.

Sorry I forgot your thread - but I've recalled a good solution to find out if a command is already used on the PATH.
It works in XP also.

Code: Select all

@echo off
"%~1" /? 1>nul 2>&1 & if errorlevel 9009 (echo "%~1" is not a command on the path) else (echo "%~1" is an existing command)

I haven't tested it... Murphy's Law says that I can get something so simple wrong though...

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Call command - accidental path interference

#9 Post by Aacini » 05 Dec 2015 09:20

Many years ago I wrote the Batch file below (called PATHOF.BAT), that should run in Windows XP:

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM CREATE A LIST OF FILE NAMES ADDING THE EXECUTABLE EXTENSIONS
SET NAMEEXT=!PATHEXT:.=%1.!
REM SEARCHES FILE NAMES IN CURRENT DIRECTORY, IF FOUND: ERRORLEVEL=1
FOR %%N IN (%NAMEEXT%) DO IF EXIST %%N ECHO %%N & EXIT /B 1
REM SEARCHES FILE NAMES IN DIRECTORIES OF PATH VARIABLE, IF FOUND: ERRORLEVEL=2
FOR %%N IN (%NAMEEXT%) DO IF NOT "%%~$PATH:N" == "" ECHO %%~$PATH:N & EXIT /B 2
REM IF FILE NOT FOUND, ERRORLEVEL=0
ECHO '%1' is not an external command or batch file located in PATH & EXIT /B 0

For example:

Code: Select all

C:\> pathof where
C:\Windows\System32\where.exe

C:\> pathof copy
'copy' is not an external command or batch file located in PATH

Note that this code does not manage names with spaces, but a simple modification would allow to do so. Also, a simple modification would allow to show all names of executable files that may exist in the PATH, that is, the "hidden commands".

WHERE command does not exist in Win XP.

EDIT: I just found this info that suggest that this code does not correctly works in Win XP:

On http://www.microsoft.com/resources/docu ... /path.mspx Windows XP wrote:• Current directory

The operating system always searches in the current directory first, before it searches the directories in the command path.

• Files with the same name, different extensions

You might have some files in the same directory that share the same file name but have different extensions. For example, you might have a file named Accnt.com that starts an accounting program and another file named Accnt.bat that connects your system to the accounting system network.

The operating system searches for a file by using default file name extensions in the following order of precedence: .exe, .com, .bat, and .cmd.

• Two or more identical file names in the path

If you have two or more files in the command path that have the same file name and extension, Windows XP searches for the specified file name first in the current directory, and then it searches the directories in the command path in the order in which they are listed in PATH.

The way to fix this point is very simple; just add this command before SET NAMEEXT line:

Code: Select all

IF NOT DEFINED PATHEXT SET PATHEXT=.exe;.com;.bat;.cmd

Antonio

MiniMax
Posts: 1
Joined: 06 Dec 2015 19:33

Re: Call command - accidental path interference

#10 Post by MiniMax » 06 Dec 2015 19:50

I am sure I am missing something, but what is wrong with using:

Code: Select all

set name=where
%WINDIR%\System32\where.exe %name%

Or "simply":

Code: Select all

set name=where
for %X in (%PATHEXT%) do @for %F in (%name%%X) do @if exist %~dp$PATH:F\%F echo %~dp$PATH:F\%F

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Call command - accidental path interference

#11 Post by thefeduke » 07 Dec 2015 10:19

MiniMax wrote:I am sure I am missing something, but what is wrong with using:

Code: Select all

set name=where
%WINDIR%\System32\where.exe %name%

Aacini wrote:WHERE command does not exist in Win XP.

I started this subject with a poorly chosen topic name. There really is no point for users that have the 'where' command.
MiniMax wrote:Or "simply":

Code: Select all

set name=where
for %X in (%PATHEXT%) do @for %F in (%name%%X) do @if exist %~dp$PATH:F\%F echo %~dp$PATH:F\%F

This is magnificent. I shall 'batchify' this command to replace some of my kludge code after a small change in output formatting to eliminate \\ in the path:

Code: Select all

echo %~dp$PATH:F%F

Thanks,
John A.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Call command - accidental path interference

#12 Post by thefeduke » 09 Dec 2015 04:17

The subject of this topic has been changed for clarity and all of my code has moved to the first post. Thanks, Foxi.
foxidrive wrote:I've recalled a good solution to find out if a command is already used on the PATH.
It works in XP also.

Code: Select all

@echo off
"%~1" /? 1>nul 2>&1 & if errorlevel 9009 (echo "%~1" is not a command on the path) else (echo "%~1" is an existing command)

I haven't tested it... Murphy's Law says that I can get something so simple wrong though...

Good, that formalizes the manual method of 'command /?' that you suggested earlier.
I did incorporate that into a called pre-manufactured script in 'IsItDOS' because of problems that I was having with the script stopping. I now realize that I complicated it for nothing. If you run a command that results in a severe enough syntax error when presented with a '/?' argument everything stops like silent magic when the error messages are sent to 'nul'. I don't have the energy to bullet-proof the '/?' by starting the command in a new window with the proper path environment and retrieving the output from the failed command in my original window. ... Could be fun.

John A.

Post Reply