Batch script fails with "The system cannot find the path specified" - batch-file

I have written the following batch script, which runs another batch script on a directory, or, with addition of a flag, on a directory tree and then on an equivalent directory or directory tree on a different drive (Z:). No matter which option I choose, it outputs the error "The system cannot find the path specified." It does do what it's supposed to if I do it on just one directory, even though it gives the error. It doesn't work successfully on a directory tree. I've run it without #echo off to try understand where its failing, without success. The directory which it's trying to change into does exist.
#echo off
set origdir=%CD%
if X%~f1==X (
echo Please input a directory.
goto done
)
chdir /d %~f1
for %%X in (myotherscript.bat) do (set FOUND=%%~$PATH:X)
if not defined FOUND (
echo myotherscript is not in your PATH
)
if X%2==X/R (
goto recursive
) else ( goto single )
:recursive
for /d /r %%G in (.) do call myotherscript
echo Z:%~p1
chdir /d "Z:%~p1"
for /d /r %%G in (.) do call myotherscript
goto ended
:single
call myotherscript
echo Z:%~p1
chdir /d "Z:%~p1"
call myotherscript
goto ended
:ended
chdir /d origdir
goto done
:done
pause
Here is "myotherscript" Yes, purge does exist.
#echo off
if exist "D:\path\to\purge.bat" (
call purge
for %%f in (*.log.*) do call :renameit "%%f"
for %%f in (*.drw.*) do call :renameit "%%f"
for %%f in (*.asm.*) do call :renameit "%%f"
for %%f in (*.prt.*) do call :renameit "%%f"
goto done ) else (
echo Purge does not exist.
goto done )
:renameit
ren %1 *.1
:done
Any help would be appreciated.
Thanks

I'm not sure why this (very old) question got reactivated. But since it has, let's see if we can close this out.
There seem to be two problems here. First:
it outputs the error "The system cannot find the path specified."
This looks like a simple typo on this line:
chdir /d origdir
Without the '%' marks, this is trying to change to a directory literally named origdir, rather than the original directory the script was run from, which would be:
chdir /d %origdir%
Second problem is:
It does do what it's supposed to if I do it on just one directory, even though it gives the error. It doesn't work successfully on a directory tree.
At a guess, this is due to this line:
if X%2==X/R
"IF" is case sensitive. If you tried to run this using /r, it wouldn't see the request for recursion and would always execute single.

For me I got the "The system cannot find the path specified" due to a missing exe that seemed way later in the script. It seems that the pipes in DOS don't always output data in the order of execution. I was used to UNIX where the output from each "echo" command in a script goes in order, so I had added debug output in the .bat file to try to tell me what lines had executed.
The problem is, the error about the file not found was happening in the output log (and screen) way earlier than the echo commands would indicate. So I don't know if the WinXP cmd shell was going a few steps ahead, or it was parsing for the exe to call during startup of the called bat file or what.
It turned out it was in fact a bad path to the .exe I was running from a call'd bat script, but the echo debug statements made me think I was in a way earlier part of the script. Once I added the right path before the exe it all worked

Related

Why is my batch script hiding processed files/folders?

Can anyone here give me a hint, why my batch script marks successfully processed folders as system, hidden, non-archive? Furthermore I cannot even remove the "hidden" attribute via Explorer (probably because of the systemfolder attribute).
The script is meant to process one folder (passed to it as a parameter), looking for raw-photo files (.nef files in my case) that are marked read-only. For every read-only photo the script copies a specified file to the processed folder and renames that copy according to the photo filename.
The folder attribute mess is caused by robocopy. (Without that command there is no problem.) But it doesn't have to touch the folder at all. It only copies one file to that folder. The error only occurs, if at least one file in the folder was marked read-only and gets a sidecar file.
I already tried to move the script from system drive to desktop and start it from there. It made no difference.
(To avoid confusion: I am on a non-English Windows 10, so I used !var! instead of %var%. Hell it took some time to find that trick...)
echo off
setlocal ENABLEDELAYEDEXPANSION
chcp 65001
IF "%~1" == "" (
GOTO myWarning
) ELSE (
IF EXIST "%~1" (
GOTO myFuction
) ELSE (
GOTO myWarning
)
)
GOTO myFuction
:myWarning
echo Ordner-Pfad muss angegeben werden!
pause
GOTO:eof
:myFuction
echo Bearbeite %1
cd "%1"
for /r %%f in (*.nef) do (
set fileattr=%%~af
set readonlyattr=!fileattr:~1,1!
:: check if current file is read-only
IF !readonlyattr!==r (
:: create XMP-Sidecar file for read-only photos
echo %%f
robocopy "C:" "%1" "metadata-2stars.xmp"
rename "metadata-2stars.xmp" "%%~nf.xmp"
)
)
GOTO:eof
Sorry, after I narrowed the problem down to robocopy I found the solution. It seems to be a known bug in robocopy, e.g. described here:
https://blog.coeo.com/how-to-prevent-robocopy-from-hiding-your-files-and-how-to-fix-it-when-it-does
The solution/hotfix is simply to tell robocopy not to mark the destination as system hidden by adding /A-:SH at the end of the command. So with robocopy "C:" "%1" "metadata-2stars.xmp" /A-:SH everything works as expected.

Why does my batch file create an additional copy in current folder?

I have a folder xyz. It has a batch file which copies files from source directory abc to destination directory def. I am using copy with options /v /y.
Copy works absolutely fine. But I notice a strange or weird issue that additionally a copy of all the files copied from source to destination are present in folder xyz.
I started observing this issue after a system restart and not sure if its a one time issue. But I would like to know if someone has run into this issue before and what is the possible fix?
Here is the code:
#if not defined ECHO_ON echo off
SETLOCAL EnableDelayedExpansion
set arg1=%1
set arg2=%2
copy /v /y !arg1! !arg2!
call :getPath !arg1!
ren !arg2!\!_NAME_EXT! !_NAME!.svg
:getPath
set _NAME=%~n1
set _NAME_EXT=%~nx1
set _LOC=%~dp1
goto:eof
endlocal
Please note I am using copy and robocopy command (for some other copying operation) in same .bat file.
Is this something to be worried about?
(As I wrote things worked fine until restart.)
Your double Copy is because a batch script works line by line until it reaches an end of file marker or an exit instruction. A Call command returns back to the point just after the Call instruction. When it returns, there is no exit instruction or end of file marker until the bottom of your script, so the :getPath label is executed again.
There appears to have been absolutely no reason for EnableDelayedExpansion in your script, for Setting any variables or for a Call command. I have therefore simplified it as such:
#Echo Off
If "%~2"=="" Exit /B
If Not Exist "%~2\" MD "%~2" 2>Nul || Exit /B
If Exist "%~1" Copy /V /Y "%~1" "%~2\%~n1.svg"
I hope it helps you out.

Using BATCH file to install software (which I have working) and THEN create a shortcut file

Here is what I have so far:
IF EXIST "C:\Program Files (x86)\Yawcam\Yawcam.exe" GOTO :eof
ELSE
start \\hazel\software$\YawCam\v6.0\yawcam_install.exe /SP- /VERYSILENT
xcopy "\\hazel\software$\YawCam\Doc Cam.lnk" "C:\users\public\desktop\Doc Cam.lnk" /C /Y
:eof
pause
EXIT
Now, it installs properly, but doesn't create the shortcut. I have tried so many different combinations of switches, quotes, and statements. I just can't seem to get it to work. I would very much appreciate any help with this, because I'm sure it is just something I have simply overlooked. Thank you in advance!
The following rewrite requires to be run As administrator.
If Exist "%ProgramFiles(x86)%\Yawcam\Yawcam.exe" GoTo :EOF
"\\hazel\software$\YawCam\v6.0\yawcam_install.exe" /SP- /VERYSILENT
XCopy "%~dp0Doc Cam.lnk" "%PUBLIC%\Desktop" /C /Y
Pause
I would write it like this:
pushd "\\hazel\software$" || exit /B 1
if not exist "%ProgramFiles(x86)%\Yawcam\Yawcam.exe" (
".\YawCam\v6.0\yawcam_install.exe" /SP- /VERYSILENT
)
copy /Y ".\YawCam\Doc Cam.lnk" "%PUBLIC%\Desktop\Doc Cam.lnk"
popd
exit /B
What I did, and why:
added pushd to resolve the UNC path \\hazel\software$ as some commands might have trouble with such; || means to execute next command in case of failure, exit /B 1 exits the batch file if pushd fails, like when the path could not be found; popd at the end restores the previous working directory finally;
reversed the if query as you want something to happen in case the condition is not met; this also avoids the need of goto; in addition, never define a label :EOF as this is a reserved name (see this: goto); regard that your if/else syntax is wrong!
used environment variables for system paths, like %ProgramFiles(x86)% and %PUBLIC%, because the directory locations may be different on some systems;
removed the start command as it is usually not necessary to run external (console) programs; (if it is required for this application for some reason, you might want to change the syntax to: start "" /WAIT ".\YawCam\v6.0\yawcam_install.exe" /SP- /VERYSILENT)
replaced xcopy by copy since you are copying a single file only, in order not to having to deal with the F = file, D = directory prompt;
added switch /B to exit in order to just terminate the batch file but not the hosting command prompt (cmd) instance;
I'm not sure if this method is necessarily the best way to go about it, but it got it working for our needs! I appreciate all your guys' help with this! We looked at each comment/answer and went from there. Thank you!
Here's what we did in the end:
IF EXIST "C:\Program Files (x86)\Yawcam\Yawcam.exe" GOTO eof
ELSE
start \\hazel\software$\YawCam\v6.0\yawcam_install.exe /SP- /VERYSILENT
:eof
Echo F|xcopy "\\hazel\software$\YawCam\Doc Cam.lnk" "C:\users\public\desktop\Doc Cam.lnk" /C /Y
EXIT
Hopefully this can help someone trying to do the same in the future!

How locate a file's location and CD to the directory?

I'm making a batch that edits a document, but in order to edit, it need's to CD it its location. The problem I'm having is that in order to make it portable, I need the command to be able to locate the file's location.
I've tried:
CD C:\Users\%username%\AppData\Roaming\skype\John
CD C:\Users\%username%\AppData\Roaming\skype\%foldername%\config.xml
Any way to get to the location with the config.xml?
You can try with:
FOR /D %%G IN ("%APPDATA%\skype\*") DO IF EXIST "%%~fG\config.xml" (
set correctDir=%%G
goto :foundFile
)
echo File config.xml not found
goto :eof
:foundFile
cd "%correctDir%"
FOR /D iterates over all directories using the %%G variable. %%~fG expands to the full path to the directorie in %%G.
IF EXIST checks if a file exists.
goto :eof exits the script
EDIT: As #Compo pointed out: for portability reasons it is better to use the OS built-in environment variable %APPDATA% instead of C:\Users\%username%\AppData\Roaming.

Batch file for loop doesn't like parenthesis

I'm writing a simple batch file that will execute a block of commands for each folder in a directory. Here is my code:
for /D %%x in ("C:"*) do echo "Folder found!">>test.txt
That works. The trouble is, when I add parentheses to execute several commands in each folder, the operation crashes. It doesn't run the loop:
for /D %%x in ("C:"*) do(
echo "Folder found!">>test.txt
)
Causes a crash.
I can't find anything on google. Does anyone have any ideas?
Its simply the missing space after do change to do (
Also the pattern "C:"* is the current directory prepended with "C:", for C:\ itself;
for /D %%x in ("C:\*") do (
echo "Folder found!"
)

Resources