2

OK. My question pretty much explains itself. Is it possible to creat a batch file, that when executed will create another batch file via copy con command? Something like:

@echo off
copy con file.bat
@echo off
echo hallo
exit
^Z
start file.bat

The only problem I encountered trying to do this, was that you manualy need to hit Enter after ^Z, and I cannot find any kind of cmd command to replicate that. Does anyone know if such a thing is possible? Or is there any other way for a batch file to re-create another batch file or itself?

Thank you.

Script_Coded
  • 709
  • 8
  • 21
iNT
  • 31
  • 3
  • 1
    FYI, the `CON` device (pseudo-device prior to Windows 8) is the console input buffer when opened for reading and screen buffer when opened for writing. That's of no help regarding text stored in a file. – Eryk Sun May 30 '15 at 12:41

3 Answers3

6

It may be possible to issue an escape code for ^Z and do it with copy con but why would you? Just just normal redirection of the echo command. Like this:

@echo off
echo Generating batch file
echo echo Hello world > hello.bat
echo Now running batch file
echo ----------
call hello.bat
echo ----------
echo Ta-da!
Eli Algranti
  • 8,707
  • 2
  • 42
  • 50
  • 2
    You can also use a parenthese block to group multiple echo statements, using a single output redirection, e.g. first line: `(echo @echo off`, second line: `echo echo hello world) > hello.bat`. – Eryk Sun May 30 '15 at 12:21
  • What if I want a batch file that for example opens some files, to create another batch file that copies and pastes the openned files to another directory. Something like '@echo off start C:\Users\User1\Desktop\image1.jpg copy con imag1_copy.bat '@echo off copy C:\Users\User1\Desktop\image1.jpg C:\Users\User2\Desktop ^Z start imag1_copy.bat exit – iNT May 30 '15 at 12:21
  • What do you mean? copy con uses the copy command with input from the console. You are not using the console so you can either echo strings or type files to your generated batch file. – Eli Algranti May 30 '15 at 12:22
  • Let's give u an example to better understand. I want a batch file designed to do some certain commands, to create ANOTHER batch file to do OTHER commands. I don't want the 1st batch file to do a command and then create the 2nd batch file to do the same command. I want them to do totaly different commands but I want the 2nd to emerge from the 1st, automatically, without any manual interaction from me. – iNT May 30 '15 at 12:27
  • @iNT my example is just an example. You don't need to do "echo echo" you can generate whatever batch file you want. The important character here is the redirection ">". You could do "echo copy a b > thebatch.bat" and it would create a batch file with "copy a b" as the content. You can then use ">>" to append to it (or group the statements as suggested by @eryksun) any other commands you want. – Eli Algranti May 30 '15 at 12:35
  • Sorry for my missunderstanding but im kinda newbie to cmd. I got another question; In your example, if I do (in the 1st batch file)"echo copy a b > thebatchfile.bat" will the copy command ALSO be executed by it? or it won't execute untill I call thebatchfile.bat ? This is what I care about.. – iNT May 30 '15 at 12:41
  • no it will just echo the string "copy a b" into the batch. The part that runs the other batch in my example is the "call" command. – Eli Algranti May 30 '15 at 12:45
  • this is an example of the code i write : `@echo off start C:\Users\User\Desktop\image1.jpg echo copy C:\Users\User\Desktop\image1.jpg C:\Users\User\Saves > autosave.bat call autosave.bat exit` But it doesnt work... – iNT May 30 '15 at 12:56
  • What are you trying to do. Your batch file makes no sense. Why would you generate a batch file that you are going to call immediately? Why not execute the copy command in the same batch? – Eli Algranti May 30 '15 at 13:07
  • It was just an example. Tried to show you that I needed to create a batch file that would do a totaly diffrenet job than the 1st one. Anyway. Your advice combined with Google's helped me got throught it and I finaly managed to do it. As for the code in the previous comment, It wasn't working cause of some spelling mistakes from my part. Yet again, thank you for your help :) – iNT May 30 '15 at 13:11
  • You're welcome. You know you can also accept the answer by clicking the check mark besides the answer (hint hint) :-) – Eli Algranti May 30 '15 at 13:23
1

There are multiple ways to create a Batch file from inside another one. The methods that use echo batch code requires to escape the special characters that may appear in the "batch code". There are other methods that consist in read lines from the Batch file itself and then output such lines to the created file; in this case, the lines may have pure Batch code even if they contains special characters.

The method you used in your example is similiar to Unix heredoc feature, that is:

tr a-z A-Z << END_TEXT
one two three
uno dos tres
END_TEXT

There are several ways to simulate a "Unix heredoc" in Batch; for example this one:

@echo off

rem Definition of heredoc macro
setlocal DisableDelayedExpansion
set LF=^
% Don't remove this line 1/2 %
% Don't remove this line 2/2 %
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
set heredoc=for %%n in (1 2) do if %%n==2 (%\n%
       for /F "tokens=1,2" %%a in ("!argv!") do (%\n%
          if "%%b" equ "" (call :heredoc %%a) else call :heredoc %%a^>%%b%\n%
          endlocal ^& goto %%a%\n%
       )%\n%
    ) else setlocal EnableDelayedExpansion ^& set argv=


rem Heredoc syntax:
rem
rem %%heredoc%% :uniqueLabel [outfile]
rem contents
rem contents
rem ...
rem :uniqueLabel

rem For example:

%heredoc% :endBatch file.bat

@echo off

echo hallo
exit /B

:endBatch

echo Calling created file:
call file.bat
echo Return from created file
goto :EOF


rem Definition of heredoc subroutine

:heredoc label
set "skip="
for /F "delims=:" %%a in ('findstr /N "%1" "%~F0"') do (
   if not defined skip (set skip=%%a) else set /A lines=%%a-skip-1
)
for /F "skip=%skip% delims=" %%a in ('findstr /N "^" "%~F0"') do (
   set "line=%%a"
   echo(!line:*:=!
   set /A lines-=1
   if !lines! == 0 exit /B
)
exit /B
Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108
0

Isn't it better to do it like this? Maybe I don't know what you mean, but I think this can help you:

@echo off
>newbatch.bat (
echo @echo off
echo echo It works!
echo echo Hope it helped you :)
echo pause >nul
)
run newbatch.bat
Noam Hacker
  • 4,671
  • 7
  • 34
  • 55
Quary
  • 1