Can't pass file path to a Batch file - batch-file

I'm new to programming so apologies in advance if this is really simple.
I'm using PA File Sight to monitor a folder for open files. When a file is opened it starts a program (batch file in this case) and passes the entire file path to the variable: $Item(1)$
The batch file looks like this at the moment:
set FILE_PATH="$Item(1)$"
echo.>%FILE_PATH%_IS_OPEN
I'm trying to get the batch file to create a new file with IS_OPEN on the end of it so that users know that a file "is open"
Running the batch file creates the following in it's folder:
$Item(1)$_IS_OPEN
So it's not storing the path for some reason.

I'd suggest you try
set FILE_PATH="%~1"
echo. "%FILE_PATH%_IS_OPEN"
echo.>"%FILE_PATH%_IS_OPEN"
PAUSE
This should set FILE_PATH to the first parameter that the batch file sees - the ~ removes any enclosing quotes
The next line echoes the result to the console and may be removed if the test proves successful.
The third line encloses the proposed filename in quotes to allow the use of spaces in the filename generated.
The PAUSE holds the CMD window open until you press ENTER to allow you to see the results. It too can be removed if your results are as expected.
modified to replace the first 2 characters of the NAME portion with "AA"
set FILE_PATH="%~1"
FOR /f "delims=" %%i IN ("%file_path%") DO (SET dpi=%%~dpi&SET ni=%%~ni&SET xi=%%~xi)
SET file_path=%dpi%AA%ni:~2%%xi%
echo. "%FILE_PATH%_IS_OPEN"
echo.>"%FILE_PATH%_IS_OPEN"
PAUSE
This assumes that it's the first 2 characters that need to be replaced. It works by assuming that the literal-string in the variable file_path is a filename whic, miracle of miracles, it is. dpi is then set to the drive and path, ni to the name and xi to the extension. then the full name is reconstructed, substituting AA for the first 2 characters of the name (dpi (the path) + AA + ni:2 (the name from the second character to the end) + xi (the extension))

$Item(1)$ seems like a constant string. If $Item(1)$ is the name of an actual environment variable, your first line should be
set FILE_PATH="%$Item(1)$%"
Although that seems quite an odd name for a variable.

Related

How do I pass the full file name, including spaces, from the windows registry as a parameter to a batch file?

What I'd like to do: Add an entry to a Windows 10 context menu for specific file types (e.g. .mp4) that allows me to search for the file name on a website (in my case, IMDB). I got the entry to show up fine, but file names cut off after any space character.
Question: How do I pass the full file name, including spaces, from the windows registry as a parameter to a batch file?
.reg
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\VLC.mp4\shell\Search IMDB\command]
#="\"C:\\test.bat\" \"%1\""
test.bat
SET a="%~n1"
SET z=https://www.imdb.com/search/title/?title=
SET zz=%z%%a%
start "" %zz%
For a file name like movie.mp4 this works. However, file name cool movie.mp4 will in this case open a search page for "cool" which I'm afraid does not help me.
Any help is greatly appreciated!
Replace the spaces with + signs.
According to https://ss64.com/nt/syntax-replace.html that should be something like
SET zzz=%zz: =+%
The batch file should be:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Name=%~n1"
setlocal EnableDelayedExpansion
set "Name=!Name:%%=%%25!"
set "Name=!Name: =%%20!"
start "" "https://www.imdb.com/search/title/?title=!Name!"
endlocal
endlocal
First, read my answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? It explains in detail what is the difference between set variable="value" and set "variable=value". The latter is the recommended syntax.
Second, a URL must be percent-encoded. A normal space character must be encoded with %20 in a URL. The batch file above does that. It percent-encodes first also % in name by %25.
Note: The entire URL is not correct percent-encoded if the string assigned to the environment variable Name contains other characters than and % which need to be percent-encoded for a valid URL too.
Third, the character % must be escaped in a batch file with one more % to be interpreted as literal character even within a double quoted argument string.

Odd behavior with long file names and Win10 console VT-100 escape sequences

I have a Windows 10 batch file that runs ffprobe on all files in a directory. Each file name is displayed on the screen on a specific line. When the next file is processed the previous file name is erased and the next file name is written on the same line (so the file names don't run down the screen). I've noticed that for file names greater than 120 characters in length the VT100 escape sequences I'm using break to some extent. Here's the portion of my code that is applicable:
echo Checking files......
for %%a in ("*.*") do (
set filename=%%a
for /f "tokens=1,2,3 delims=," %%a in ('ffprobe [...]') do (
set codec=%%b
)
set /p="%ESC%[1G%ESC%[2K%%~a"<nul
)
set /p="%ESC%[A%ESC%[1G%ESC%[2K"<nul
(I've edited the ffprobe portion just so everything is more readable. ffprobe has nothing to do with the issue I'm seeing).
The escape sequences normally result in the display of the current file name, once ffprobe is finished with that file the cursor is moved to the 1st position on that line and the line (file name) is deleted. After the for loop the line is advanced down so sequence [A is used to move the line back up one so all the files display on the same line.
This has been working fine for months, but I just noticed on a very long file name that was 124 characters the file name is not erased and the next file name is displayed on the following line and the batch file runs correctly from there with that long file name remaining on the screen and the rest of my script runs below it. The way things should work is that each file name is deleted from the screen and none should be shown once this section of the batch file completes.
I deleted characters in the file name to see what number of characters would result in the escape sequences processing correctly and apparently there's a 120 character max.
Is this known behavior? This really isn't a major problem, but it is kind of annoying. Is there anyway to get around this?

Escape characters of a file path argument for a batch file

I was making a batch file to take dragged-and-dropped folders for program input. Everything was working fine until I passed a folder, which for the sake of this post, called foo&bar.
Checking what %1 contained inside the batch file looked like C:\path\to\foo or C:\path\to\foo\foo. If the file path were in quotes it would work, so the only working code that slightly takes this into effect is :
set arg1=%1
cd %arg1%*
set arg1="%CD%"
Which changes directory to the passed argument using wildcards. However this only works once for if there is another folder with un-escaped characters inside the parent folder, passing the child folder would result in the parent folders' value.
I tried the answer of this post, which suggests to output the argument using a remark and redirection statement during an #echo on sequence. However no progress occurred in rectifying the problem. Any suggestions?
To recap, I am looking for ways to pass folders with un-escaped characters as arguments to a batch file. The implementation should preferably be in a batch file, but answers using VBScript are welcome. However the starting program must be in batch as this is the only program of the 3 that accepts files as arguments.
To test this, create a batch file with following code:
#echo off
set "arg1=%~1"
echo "the passed path was %arg1%"
pause
Then create folders called foobar and foo&bar. Drag them onto the batch file to see their output. foo&bar will only return C:\path\to\foo.
OK, so the problem is that Explorer is passing this as the command line to cmd.exe:
C:\Windows\system32\cmd.exe /c ""C:\path\test.bat" C:\path\foo&bar"
The outermost quotes get stripped, and the command becomes
"C:\working\so46635563\test.bat" C:\path\foo&bar
which cmd.exe interprets similarly to
("C:\working\so46635563\test.bat" C:\path\foo) & bar
i.e., bar is considered to be a separate command, to be run after the batch file.
The best solution would be to drag-and-drop not directly onto the batch file but onto, say, a vbscript or a Powershell script or a plain old executable. That script could then run the batch file, either quoting the argument appropriately or putting the directory path into an environment variable rather than on the command line.
Alternatively, you can retrieve the original command string from %CMDCMDLINE% like this:
setlocal EnableDelayedExpansion
set "dirname=!CMDCMDLINE!"
set "dirname=%dirname:&=?%"
set "dirname=%dirname:" =*%"
set "dirname=%dirname:"=*%"
set "dirname=%dirname: =/%"
for /F "tokens=3 delims=*" %%i in ("%dirname%") do set dirname=%%i
set "dirname=%dirname:/= %"
set "dirname=%dirname:?=&%"
set dirname
pause
exit
Note the exit at the end; that is necessary so that cmd.exe doesn't try to run bar when it reaches the end of the script. Otherwise, if the part of the directory name after the & happens to be a valid command, it could cause trouble.
NB: I'm not sure how robust this script is.
I've tested it with the most obvious combinations, but YMMV. [It might be more sensible to use delayed expansion exclusively, I'm not sure. It doesn't seem to be necessary except in the first set command. Jeb's answer here might be a better choice if you're going this route.]
For the curious, the script works like this:
Load the original command line into dirname [necessary for the reason pointed out by jeb]
Replace all the & characters with ?
Replace all the quote marks with *
If a quote mark is followed by a space, suppress the space.
NB: it is necessary to suppress the space to deal with both the case where the path contains a space (in which case Explorer adds quote marks around it) and the case where it doesn't.
Replace all remaining spaces with /
NB: ? * and / are illegal in file names, so these replacements are safe.
At this point the string looks like this:
C:\Windows\system32\cmd.exe//c/**C:\path\test.bat**C:\path\foo?bar**
So we just need to pull out the third asterisk-delimited element, turn any forward slashes back into spaces and any question marks back into ampersands, and we're done. Phew!

batch Only execute for certain extension

I don't really have a very deep understanding of what I'm doing here but the thing is I cant make it work for just certain file type
FOR %%2 in (*.mp4,*.avi,*mkv) do set fname=%%~n2
FOR %%1 in (*.srt,*.sub) do (
attrib -r %1
PING 1.1.1.1 -n 1 -w 1000 > NUL
cscript "NewReplace.vbs" %1
ren %1 "%fname%".srt
)
So what it DOES is that this is located into %appdata%\Microsoft\Windows\SendTo and when I Right Click-Send to-MyBatch it searches for a MP4, AVI, MKV in the clicked file directory, copies it's name to my file and appends .srt.
What I WANT IT to do is only accept .srt and .sub files, and when it copies the name to append the original extension not always .srt.
Fundamentally, FOR %%2... and similar are errors.
The metavariable (loop-control variable - you've attempted to use 2) must be alphabets and that alphabetic character is case-sensitive (one of the few placs in batch that exhibits case-sensitivity.)
When referencing the value within a for loop, use %%x (where x is your chosen metavariable.)
%n where n is 1..9 means the parameter n provided to the routine, hence %1 means 'the first parameter given to this routine,' so thisroutine something somethingelse would see something as parameter 1 and somethingelse as parameter 2, referenced by %1 and %2 respectively.
Your first line, when corrected, will assign the name part of each filename found in turn from the selected masks (*.mp4,*.avi,*mkv) and the name part of the very last such name found will be assigned to the variable fname.
Similarly, your second for loop will look for all .srt and .sub files, remove any read-only attribute, wait, run your cscript with the entire name (name+extension) of the *.srt or *.sub found, then attempt to rename that file to the name found in the first loop.srt - because that is what you've specified.
The upshot of all this is that the first loop will locate zzz.mkv (if that is the last filename found in the first loop) and assign zzz to fname.
The second loop will rename the first .srt or .sub file found to zzz.srt and since that filename now exists, will fail to rename all of the remaining .srt and .sub files - including zzz.srt.
That's what your code, when the metavariables are fixed, should try to do. It probably isn't what you want it to do, but you've not provided an example, and you've not clearly explained what to do if there are multiple (*.mp4,*.avi,*mkv) files or what your cscript is supposed to do when provided with a filename, or what you want to do about srt and sub files

search and replace file names - bug fix

I have a script that changes particular string within files names (the file stores in "my_folder"):
Set objFso = CreateObject("Scripting.FileSystemObject")
Set Folder = objFSO.GetFolder("g:\my folder")
For Each File In Folder.Files
sNewFile = File.Name
sNewFile = Replace(sNewFile,"._epf","_v0_1._epf")
if (sNewFile<>File.Name) then
File.Move(File.ParentFolder+"\"+sNewFile)
end if
Next
the scrpit works fine if there are no folders under "g:\my folder", otherewise, if there are folders in "my folder" and the name of one (or more) of those folders are similiar to some file name, the scrip cause unwanted results like multiplying the replace string.
for example if "my folder" contain:
hello (folder)
hello_.epf (file)
then the script will eventually change the file name to:
hello_v0_1_v0_1._epf (unwanted result)
and i want the result to be:
hello_v0_1._epf
I'll appreciate quick help in this manner.
thanks.
I haven't bothered to try to figure out where your VBScript is going wrong. But you tagged your question with batch-file, batch, and batch-rename.
Here is a simple one-liner that can be run from the command prompt that will do what you want. It doesn't even need a batch script.
for %F in ("g:\my folder\*._epf") do #ren "%F" "%~nF_v0_1%~xF"
If you want to run the command within a batch script, then you need to double all percents.
#echo off
for %%F in ("g:\my folder\*._epf") do ren "%%F" "%%~nF_v0_1%%~xF"
EDIT
The above will append a new version suffix to each file name, before the extension.
If you want to replace an existing version number, then the solution is even easier. I'm assuming that your version always starts with _v, and v will never occur in the file extension.
ren "g:\my folder\*_v0_1._epf" "*v0_2.*"
The above command renames all files that end with _v0_1._epf. It preserves all characters up through the last occurance of v in the name, then adds the new version number, and finally appends the original extension.
See How does the Windows RENAME command interpret wildcards? for rules on how REN uses wildcards.

Resources