I want to iterate on the files selected by the user when the batch command was called via the context menu of win explorer.
I've searched but haven't been able to find how to do it. So the question is: is it possible? If so, how to do it?
The list of files that get passed in to your script will be stored in the %* parameter. To iterate through them without knowing how many there are, you can use this:
for %%A in (%*) do (
<the rest of your code here, using %%A to represent each file>
)
If your code is too long to be wrapped in a for loop, you can write a second batch file that calls your initial code.
#echo off
for %%A in (%*) do call yourscript.bat %%A
Related
i have a batch file which i've just got working and inside it is this:
for /f "tokens=1,2,3 delims=," %%a in (people.csv) do (
echo ^<Grid Background^="Red" x:Name^="ContentPanel" Margin^="12,0,12,0"^>^<StackPanel Margin^="20" Background^="Blue" PointerPressed^="commonHandler"^>^<TextBlock x:Name^="firstTextBlock" FontSize^="30" ^> %%a ^</TextBlock^>^<TextBlock x:Name^="secondTextBlock" FontSize^="30" ^> %%b ^</TextBlock^>^<TextBlock x:Name^="thirdTextBlock" FontSize^="30" ^> %%c ^</TextBlock^>^</StackPanel^>^</Grid^> >>%%a.xaml
)
That is a just an xaml file that i cut out and echoed into the batch file, but the people that are going to use this system aren't IT literate and so i need to get rid of all that code and put it in an external file and then include that text file into this file so then the users can edit the external text file instead of the batch file.
If that didnt make any sense, im sorry...
Ive tried putting it in another for loop but that didnt do anything...
I sort of thought of it as a 'php include' sort of thing?
Thank you
#echo off
call included.bat %*
rem do other stuff...
this will execute included.bat with the same arguments as the current file, and it will execute exactly when it is called. be sure to specify the full path. also, you can pass any arguments you want, or none.
I have a list of files in a folder that end with .swf.
I want to change all those files from X.swf to X<some number>.swf.
How can I do that?
This little script will change all *.swf files into the equivalent *_42.swf files.
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f %%a in ('dir /b *.swf') do (
set fspec=%%a
set newfspec=!fspec:~0,-4!_42.swf
echo ren !fspec! !newfspec!
)
endlocal
Actually, as it stands now, it will just echo the commands that it wants to execute. Once you're happy they're correct, you can just remove the echo from that renaming line above.
It works by using for /f to get a list of all SWF files and then using string manipulation to:
remove the last four characters (the.swf extension); then
add a new _42.swf extension onto the end.
And, please, make sure you back them up first :-)
You could use the following one-liner directly from the command prompt:
FOR %F IN (*.swf) DO RENAME "%F" "%~nF123.*"
where 123 stands for your number of choice.
Alternatively you could create a batch file and take advantage of its ability to accept parameters. Use the following script:
#ECHO OFF
SET "suffix=%~1"
FOR %%F IN (*.swf) DO RENAME "%%F" "%%~nF%suffix%.*"
Now if the batch's name is renamer.bat, you can invoke it like this:
renamer.bat 2011
and it will add 2011 to the name of every .swf file in the current directory.
Assuming <X> in your description is supposed to be constant and you don't explicitly require a batch script to solve your problem, you can use Windows Explorer as mentioned in an article by Microsoft titled "Rename a file".
Here's a an extract from said article:
"You can also rename several files at one time, which is useful for grouping related items. To do this, select the files [then press F2]. Type one name, and then each of the files will be saved with the new name and a different sequential number at the end (for example, Renamed File (2), Renamed File (3), and so on)."
I'm not sure whether it is possible, but what I need is a plain bat/cmd file that runs on windows 7 and does such things:
Step 1. findstr - it should find a specific string using regular expressions engine. Suppose we're looking for a number enclosed in tags <id>123</id> (suppose such a file is unique, so one value is returned). The command would print 123 to the screen, but I need to save it in a variable (don't know how).
Step 2. Another call to findstr on another directory. Now we want to find a file NAME (/m option) containing the value that we saved on Step 1 (in another group of files i.e. another directory). And again, save the result (name of the file) in a variable. Say, file_123.txt matches the criteria.
Step 3. Copy the file that we got as a result of the second findstr call (file_123.txt) to another location.
The whole question turns around the point about how to save the result of windows commands to variables to be able to provide these values to subsequent commands as parameters.
The general way of getting command output in variables is
for /f %%x in ('some command') do set Var=%%x
(with various variations, depending on context and what exactly is desired).
As for your steps, I elaborate after lunch. There are some intricacies.
Step 1:
FOR /F "USEBACKQ tokens=1-20 delims=<>" %%A in (`FINDSTR "123" "path of file to search in"`) DO (
SET var=%%B
)
ECHO %var%
Understand that delims will change depending on what 'separates' the parts of the output (whether its a space, a special character, etc.)
Step 2 & 3:
FOR /F "USEBACKQ tokens=*" %%A IN (`DIR "Path" /A ^| FIND /I "%var%"`) DO (
COPY /Y "%%A" "C:\New\Path\%%~nxA"
)
I can already get a batch file to run when a user right clicks on a file type. How can I make it so that only one instance runs per highlighted group and gets all the files as arguments.
Currently it runs single instance per file when a user "shift clicks"
there is most likely a better way to word this... you can see why I had trouble googling it.
thanks
Normally a file association multi-selection invocation will start several instances of a program and the program itself would have to deal with it on its own (Or with the help of DDE or IDropTarget)
It is going to be very hard to implement this in a batch file, this example should get you started:
#echo off
setlocal ENABLEEXTENSIONS
set guid=e786496d-1b2e-4a49-87b7-eb325c8cc64d
set id=%RANDOM%
FOR /F "tokens=1,2,3 delims=.,:/\ " %%A IN ("%TIME%") DO SET id=%id%%%A%%B%%C
set sizeprev=0
>>"%temp%\%guid%.lock" echo %id%
>>"%temp%\%guid%.list" echo %~1
:waitmore
>nul ping -n 3 localhost
FOR %%A IN (%temp%\%guid%.list) DO set sizenow=%%~zA
if not "%sizeprev%"=="%sizenow%" (
set sizeprev=%sizenow%
goto waitmore
)
FOR /F %%A IN (%temp%\%guid%.lock) DO (
if not "%%A"=="%id%" goto :EOF
FOR /F "tokens=*" %%B IN (%temp%\%guid%.list) DO (
echo.FILE=%%B
)
del "%temp%\%guid%.list"
del "%temp%\%guid%.lock"
pause
)
While this works, it is a horrible horrible hack and will fail badly if you don't wait for the first set of files to be parsed before starting a new operation on another set of files.
If you create a batch file and place it on your desktop, then you can select multiple files and drop them on that batch file. They will get passed as multiple parameters to the file.
For example, assume you put dropped.bat on your desktop, and it looks like this:
#echo off
echo %*
pause
Now assuming you had three files x, y and z, if you multiple-selected them and dropped them on dropped.bat, you'd see a command window come up with this text in it:
C:\Users\alavinio\Desktop\x C:\Users\alavinio\Desktop\y C:\Users\alavinio\Desktop\z
Press any key to continue . . .
That's the closest you can get. The right-click-and-Open semantics expect to start a new executable for each selected item, and typically those executables check for another instance of themselves, and if they see one, send the parameter over there to that existing process, and terminate themselves. You can actually watch that happen with Task Manager or Process Explorer.
Late to the party but here is my 2 cents. I had the same problem when trying to customise the behaviour of a 'Move to Dropbox Folder...' context menu command. I needed every file selected to be piped to a batch file to handle the processing in one instance.
After some digging I found Context Menu Launcher.
Simple enough to use. I popped singleinstance.exe in C:\Windows\system32 and created and ran a .reg file similar to below.
Windows Registry Editor Version 5.00
; Documents
[HKEY_CLASSES_ROOT\SystemFileAssociations\document\Shell\Dropbox]
#="Move to Dropbox Folder"
"Icon"="%SystemRoot%//system32//imageres.dll,-112"
"MultiSelectModel"="Player"
[HKEY_CLASSES_ROOT\SystemFileAssociations\document\Shell\Dropbox\command]
#="singleinstance.exe \"%1\" \"C:\\Move to Dropbox Folder.bat\" $files --si-timeout 400"
The way it works seems to have been imposed on you by the shell, and there doesn't seem to be an easy way to solve this.
Some application would add its own menu item that would allow the app to be invoked differently (i.e. just once for the group) from how it is done generally (repeatedly for every selected item), while another one would employ the API to check its own presence and would redirect the 'open' request to its already running copy.
Batch files aren't meant for either of these. You would probably need a different tool. Even if you would like the main job to be done by the batch file, you'd still need a way to call the batch file for processing of the item list.
I'm guessing you have a group of highlighted files and you want to run some program for each file.
#echo off
for %%A in (%*) do echo %%A
pause
How would I go about reading an entire directory and blanking files with a specific extension? I have an application that reads the content of a specific folder and returns an error if a file is missing, however it does't check to see if the files are valid, so I want to make them NULL to get around the checks.
if by 'blanking' you mean truncating them, you could use the following:
for /f %%a in ('dir *.[my ext]') do (echo . > %%a)
note that the double % is for use within a batch file. if you are running this from a command line, use a single %.
EDIT:
to incorporate #Loadmaster's improvement:
for /f %%a in ('dir *.[my ext]') do (type nul > %%a)
First, create an empty file. Call it "blank". You can use Notepad to just save an empty file, for example.
Let's suppose the specific extension is ".xyz". Run this:
for %f in (*.xyz) do copy /y blank %f
The for loop sets variable "%f" to each file name in turn, and runs the copy command. The copy command copies the blank file on top of each matching file.
By the way, you can find out more about the for command using the help command:
help for
You could make the batch file take the filter and then it's much more useful.
#for %%i in (%1) do cd.>%%i
Usage (if you call it empty.bat):
empty *.c