Windows: establish file association to batch file - windows

I created a custom file extension I would associate to a batch script.
I used
ASSOC .myext=MY.FILETYPE
FTYPE MY.FILETYPE=cmd /c "C:\Path\of\my\batch.bat" %1 %*
by now the batch file "C:\Path\of\my\batch.bat" is a simple one-liner
echo %1
And roughly works: double clicking a .myext file pops up a cmd shell echoing the file path.
But a problem arises when the .myext file is in a path containing spaces: the echoed filepath is truncated to the space.
Double quoting the %1 in the FTYPE statement seems not to work.
FTYPE MY.FILETYPE=cmd /c "C:\Path\of\my\batch.bat" "%1" %*

Double quoting %1 is correct, but it fails as cmd.exe contains a bug when the command and at least one parameter contains quotes.
So you need to make the command without quotes by inserting CALL.
FTYPE MY.FILETYPE=cmd /c call "C:\Path\of\my\batch.bat" "%1" %*

Change the batch file "C:\Path\of\my\batch.bat" content to
echo %*
Your ASSOC and FTYPE statements seem to be all right.
Edit accordig to Monacraft's comment.
This solution is correct as %1 will reference the document filename while that %* will reference to further parameters: If any further parameters are required by the application they can be passed as %2, %3. To pass all parameters to an application use %*.
Handy for using aFile.myext a b c right from command line, although for that use the FTYPE statement should be
FTYPE MY.FILETYPE=cmd /D /C "C:\Path\of\my\batch.bat "%1"" %*
to differentiate first parameter if contains spaces.
Example: with
ASSOC .xxx=XXXFILE
rem a bug here FTYPE XXXFILE=%ComSpec% /D /C "d:\bat\xxxbatch.bat "%1"" %*
rem definitely switched to Jeb's solution as follows
FTYPE XXXFILE=%comspec% /D /C call "d:\bat\xxxbatch.bat" "%1" %*
and xxxbatch.bat as follows
#echo(
#echo %*
#if "%2"=="" pause
#goto :eof
Output:
d:\bat>D:\test\xxxFileNoSpaces.xxx aa bb cc
"D:\test\xxxFileNoSpaces.xxx" aa bb cc
d:\bat>"D:\test\xxx file with spaces.xxx" dd ee
"D:\test\xxx file with spaces.xxx" dd ee
d:\bat>

if you are using this from a bat file try to change it to:
ASSOC .myext=MY.FILETYPE
FTYPE MY.FILETYPE=cmd /c "C:\Path\of\my\batch.bat" "%%1" %%*
I think even
FTYPE MY.FILETYPE="C:\Path\of\my\batch.bat" "%%1" %%*
should work.

Related

How to process 2 FOR loops after each other in batch?

My problem is that two FOR loops are working separately, but don't want to work one after another.
The goal is:
The first loop creates XML files and only when the creation has already been done the second loop starts and counts the size of created XML files and writes it into .txt file.
#echo off
Setlocal EnableDelayedExpansion
for /f %%a in ('dir /b /s C:\Users\NekhayenkoO\test\') do (
echo Verarbeite %%~na
jhove -m PDF-hul -h xml -o C:\Users\NekhayenkoO\outputxml\%%~na.xml %%a
)
for /f %%i in ('dir /b /s C:\Users\NekhayenkoO\outputxml\') do (
echo %%~ni %%~zi >> C:\Users\NekhayenkoO\outputxml\size.txt
)
pause
This question can be answered easily when knowing what jhove is.
So I searched in world wide web for jhove, found very quickly the homepage JHOVE | JSTOR/Harvard Object Validation Environment and downloaded also jhove-1_11.zip from SourceForge project page of JHOVE.
All this was done by me to find out that jhove is a Java application which is executed on Linux and perhaps also on Mac using the shell script jhove and on Windows the batch file jhove.bat for making it easier to use by users.
So Windows command interpreter searches in current directory and next in all directories specified in environment variable PATH for a file matching the file name pattern jhove.* having a file extension listed in environment variable PATHEXT because jhove.bat is specified without file extension and without path in the batch file.
But the execution of a batch file from within a batch file without usage of command CALL results in script execution of current batch file being continued in the other executed batch file without ever returning back to the current batch file.
For that reason Windows command interpreter runs into jhove.bat on first file found in directory C:\Users\NekhayenkoO\test and never comes back.
This behavior can be easily watched by using two simple batch files stored for example in C:\Temp.
Test1.bat:
#echo off
cd /D "%~dp0"
for %%I in (*.bat) do Test2.bat "%%I"
echo %~n0: Leaving %~f0
Test2.bat:
#echo %~n0: Arguments are: %*
#echo %~n0: Leaving %~f0
On running from within a command prompt window C:\Temp\Test1.bat the output is:
Test2: Arguments are: "Test1.bat"
Test2: Leaving C:\Temp\Test2.bat
The processing of Test1.bat was continued on Test2.bat without coming back to Test1.bat.
Now Test1.bat is modified to by inserting command CALL after do.
Test1.bat:
#echo off
cd /D "%~dp0"
for %%I in (*.bat) do call Test2.bat "%%I"
echo Leaving %~f0
The output on running Test1.bat from within command prompt window is now:
Test2: Arguments are: "Test1.bat"
Test2: Leaving C:\Temp\Test2.bat
Test2: Arguments are: "Test2.bat"
Test2: Leaving C:\Temp\Test2.bat
Test1: Leaving C:\Temp\Test1.bat
Batch file Test1.bat calls now batch file Test2.bat and therefore the FOR loop is really executed on all *.bat files found in directory of the two batch files.
Therefore the solution is using command CALL as suggested already by Squashman:
#echo off
setlocal EnableDelayedExpansion
for /f %%a in ('dir /b /s "%USERPROFILE%\test\" 2^>nul') do (
echo Verarbeite %%~na
call jhove.bat -m PDF-hul -h xml -o "%USERPROFILE%\outputxml\%%~na.xml" "%%a"
)
for /f %%i in ('dir /b /s "%USERPROFILE%\outputxml\" 2^>nul') do (
echo %%~ni %%~zi>>"%USERPROFILE%\outputxml\size.txt"
)
pause
endlocal
A reference to environment variable USERPROFILE is used instead of C:\Users\NekhayenkoO.
All file names are enclosed in double quotes in case of any file found in the directory contains a space character or any other special character which requires enclosing in double quotes.
And last 2>nul is added which redirects the error message output to handle STDERR by command DIR on not finding any file to device NUL to suppress it. The redirection operator > must be escaped here with ^ to be interpreted on execution of command DIR and not as wrong placed redirection operator on parsing already the command FOR.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
cd /?
dir /?
echo /?
for /?
And read also the Microsoft article Using command redirection operators.
You need to use the START command with the /WAIT flag when you launch an external application.
I believe it would look something like this:
START /WAIT jhove -m PDF-hul -h xml -o C:\Users\NekhayenkoO\outputxml\%%~na.xml %%a
That should cause the batch file to pause and wait for the external application to finish before proceeding.

windows cmd enabledelayedexpansion not working

I'm having trouble running !var! examples ad described here http://ss64.com/nt/delayedexpansion.html
Instead of the expected variable content output as the example describes, I get the literal "bang V A R bang" output, any idea?
C:\>Setlocal EnableDelayedExpansion
C:\>Set _var=first
C:\>Set _var=second& Echo %_var% !_var!
first !_var!
thanks.
You are getting an unexpected result because you are issuing the commands at the command prompt. Create a batch file by putting the following commands in a file with a .bat extension then run the batch file.
#echo off
Setlocal EnableDelayedExpansion
Set _var=first
Set _var=second& Echo %_var% !_var!
E.g., if I created a batch file named delayedexp.bat with the above contents, I would see the following when I run it:
C:\Users\JDoe\Documents\>delayedexp
first second
setlocal only works within the confines of a command script:
help setlocal
If you have access to the parameters of the cmd call, you can set parameter /v. Must be first. And use ! instead % for variables.
%windir%\system32\cmd.exe /v /c set a=10&echo a=!a!&echo My Path is %CD%&pause
This is how, for example, you can get the date in the Russia-France format directly in the Windows shortcut, where a simple percentage is impossible due to its doubling. In std queries with the /v parameter, both a percentage and an exclamation mark will work fine, but single % for cicles.
%windir%\system32\cmd.exe /v /c echo off&for /F "tokens=1-6 delims=:., " %A In ("!date! !time!") Do (Echo %A.%B.%C %D:%E:%F)&pause

Running a non bat extension file as a batch file

Let's say I have a text file, it contains batch commands. How can I run that text file as a batch file from within one, without renaming it. I want too keep a portable aspect too it, so no registry keys or such.
The reason for no renaming is too prevent leftover unrenamed files upon unexpected closure.
The simplest way is this:
cmd < file.txt
As in the previous answers, there are several commands that will not work in this file, like GOTO, SETLOCAL and others. However, multiline nested if and for commands do work as long as for replaceable parameters use just one percent (like in the command-line).
Although this method alaways show in the screen the executed commands (#echo off not works here), you may redirect the output to NUL and in the "Batch" file redirect the desired output to CON. For example, this is test.txt:
#echo off
echo Hello World! > CON
(for /L %a in (1,1,10) do (
echo Turn: %a
if %a equ 4 echo TURN NUMBER FOUR!
)) > CON
Output example:
C:\> cmd < test.txt > NUL
Hello World!
Turn: 1
Turn: 2
Turn: 3
Turn: 4
TURN NUMBER FOUR!
Turn: 5
Turn: 6
Turn: 7
Turn: 8
Turn: 9
Turn: 10
type some.txt>temp.bat
call temp.bat
del /q /f temp.bat
Is creating a temp file cheating?It's not mentioned as restriction in the question.Though you can loose the %ERRORLEVEL% because of the del command , but you can keep it in temp variable:
type some.txt>temp.bat
call temp.bat
set temp_el=%errorlevel%
del /q /f temp.bat
exit /b %temp_el%
I'm pretty sure you cannot do what you want. Windows will not let you configure the OS to recognize any other extensions as batch files. Only .bat and .cmd are supported.
You could process a series of simple commands within a text file using a FOR /F loop, but it will be very restrictive. For example, it will not support IF, FOR, GOTO Label, or CALL :Label. There are probably other restrictions. Within your main batch file, you could have the following:
for /f delims^=^ eol^= %%A in (script.txt) do %%A
You might be able to support IF and/or FOR if you execute the command via a new CMD.EXE shell, but then you cannot preserve the value of variables that might be SET by the command.
for /f delims^=^ eol^= %%A in (script.txt) do cmd /c "%%A"
See the windows shell commands
assoc. Associates a filename extension (e.g. *.txt) with a file type.
ftype. Lets you create a new file type that tells the windows shell how to open a particular kind of file.
From a command prompt, typing assoc /? or ftype /? will get you help on them. Or use your google-fu to find the MS docs.
*.bat is mapped to the file type batfile; *.cmd is mapped to the file type cmdfile. In windows 7 they are identical. If you want to be able to run files named *.foobar as a batch files, just type:
assoc .foobar=cmdfile
Then, assuming a file named 'sillyness.foobar' existing on the path, you just just type
c:\> sillyness
and it will find sillyness.foobar and execute it as a batch file. The Windows shell has a priority for how it resolves conflicts when you have files with the same name and different extensions (.com vs .cmd vs .bat, etc.)
Something like
assoc .pl=perlscript
ftype perlscript=perl.exe %1 %*
will set you up to run perl scripts as if they were .bat files.
If your batch commands are simple sequential ones then you could use this at the command prompt. Double the % signs for use in a batch file.
for /f "delims=" %a in (file.txt) do %a

Command works in Command Prompt but not in a batch file

Trying to print out the 8dot3 name of a file, it does works when I paste the line in the Command Prompt but not when I run it from a batch file.
Result when pasted :
D:\tmp>cmd /e:on /c for %A in (8088_othello.com) do #echo %~nxsA
8088_O~1.COM
Result from batch file :
D:\tmp>lfn.bat
D:\tmp>cmd /e:on /c for ~nxsA
~nxsA was unexpected at this time.
What else is needed to make it work inside a batch file ?
you need to escape % is batch files
just type
cmd /e:on /c for %%A in (8088_othello.com) do #echo %%~nxsA

Create a batch file to show all file content with file parameters

I would like to create a batch script which will give me parameters like #fname,#fdate,#fsize
i have already used the below
#forfiles /p path /m A*.bak /c "cmd /c echo #fsize #fname #fdate,#ftime"
but the #fsize gives only 10 digit size, not beyond that hence loosing correct information
i have also tried with
for %I in (E:\*.txt) do #echo %~znI
but it doesn't work in the bat file.
Is there any other option to get only the output not other comments along with it like DIR command. Thank you in advance for your help.
This will do a similar job from the command line. Double all % to %% to use it in a batch file.
for %a in (A*.bak) do #echo %~za "%~na" %~ta

Resources