How can I write a batch file that runs cmd.exe, enters the partial command robocopy then waits for user input to complete and execute the robocopy command? It seems like it should be the simplest thing to do but no method I've tried enters the command in such a way as to hold and wait for user input and then successfully execute the completed robocopy command
For example:
#echo off
set var="robocopy "
cmd.exe %var%
appears to work but then, for example, user-inputting /? to bring up robocopy's info instead brings up cmd.exe's info
Another example:
#echo off
cmd /k robocopy
Runs robocopy with no destination/source folders or switches, then closes robocopy and waits for a new user-inputted command.
what I'm trying to do is have a batch file that when I click it a cmd window will open with the partial command robocopy already entered ready for me to complete the command with source/destination/switches and execute it with an enter key press - I use robocopy all day long so this would be a big time saver.
it's not possible in the way you seem to think. That would mean to mess with the keyboard buffer (was pretty common with the C64 back in those times, but it's not possible in (pure) batch).
But the following should give you a good start for automation. It assumes, you use the same parameters each time and just want to give it a source and a destination folder. Adjust to your needs (especially the params - I added /L to prevent it from unwanted actions while testing):
#echo off
set "command=robocopy"
set "params=/L /E /MOV /MT:12 /FP /log+:robocopy.log /TEE"
set /p "source=Enter Source: "
set /p "destin=Enter Destination: "
%command% "%source%" "%destin%" %params%
The cmd.exe or cmd.exe /k isn't necessary, until you want robocopy to work in a new window.
Related
With my .bat I would like to:
open the xlsx file,
waiting 2 min,
close the file with save options
copy this file to another folder.
For now I can copy and paste the file, but I don't know how to open it, with a cmd function, and save it.
Thank you for your help.
My code is :
#echo off
cmd "O:\XXXX\*.*"
xcopy/y "O:\XXXX\*.*" "O:\XXX\"
pause
Marie (TooLong;ToRead) in disjointed comments
I suggested, A simpler alternative method to do what you need on this
occasion is to use a simple command line tool see Orlandos Sendkeys
Utility (the example is almost what you want to do)
download sendkeys from cpap.com.br/orlando
see how the demo runs
open excel with a blank sheet and at a CMD> run this demo string
SendKeys.exe 1.5 10 "Microsoft Excel" "Hello!~{PAUSE 2}After 2s.~{PAUSE 2}%(FS)~"
adapt to your own version of excel keys since the %(FS) is ALT File Save in English
you replied
#KJ Thank you, KJ, unfortunately I can't download Orlando with my PC.
So we continue to doing it in a more dirty fashion, but you still need a means to save the file by invoking an autosave which would most easily be done using an extended excel macro in your source .xlsm, anyway
after all these changes your non working file should now be replaced in your question as
#echo off
start "Excel Running" /MIN EXCEL.EXE "\\XXX\Fichier.xlsm"
REM add a delay of **2 minutes !** whilst sheet recalculates before saving a copy
timeout 120
REM copying a file that has NOT been saved using keys at this point will NOT
REM be what you really need to solve your problem unless you use a macro ?
REM see Later
xcopy/y "\\XXX\Dossier_avant*.*" "\\XXX\Dossier_apres\"
REM add a 3 second delay to check above worked but is not really needed
timeout 3
REM temporary for debugging. Later just REM it out
TASKLIST /M |Find /i "exce"
REM this line should be working with either a SUCCESS: or ERROR:
TASKKILL /T /F /IM excel.exe
REM keep this line for seeing errors above, once happy, it can become REM PAUSE
PAUSE
I think that IF you are constrained (by IT policy) to the command line it is best you write your own autosaving macro, however, MY problem is I dont know if you need it for more than one input.xlsm.
So save this as OpenRunSaveExit.vbs in your working folder where your .bat is. There is a reason I did NOT use spaces or & in the name for a later step.
Set WshShell = WScript.CreateObject("WScript.Shell")
' You may need to include the path to excel.exe if it is a portable version like mine
WshShell.Run "EXCEL.EXE "+"\\XXX\Fichier.xlsm", 9
' 120000 milli-seconds = 2 minutes
WScript.Sleep 120000
' These are the English key combinations for ALT+File+Save . SO alter or remove if not needed
WshShell.SendKeys "%FS"
' These are the English key combinations for ALT+File+eXit . SO alter if needed for french excel
WshShell.SendKeys "%FX"
' Lets us wait 2 seconds for clean closure
WScript.Sleep 2000
As Peter has pointed out in his answer you need to /WAIT before xcopy and depending on how your vbs file handling is set-up you may not need Wscript in the start line
NOW replace your .bat with this
#echo off
start /WAIT Wscript OpenRunSaveExit.vbs
xcopy/y "\\XXX\Dossier_avant*.*" "\\XXX\Dossier_apres\"
pause
And check it runs without the need for taskkill.
Finally why use a 2-4 line .bat since a desktop shortcut would potentially be easier to use. So make a shortcut for the .vbs file (right click the .vbs, and in English its Create Shortcut) and wherever it is built move it to your desktop.
Then change the properties like this (where & has a special meaning so the .vbs filename must NOT have spaces or &.)
%comspec% /c "start /wait wscript.exe OpenRunSaveExit.vbs & xcopy/y "\\XXX\Dossier_avant*.*" "\\XXX\Dossier_apres\" & pause"
P.S. I forgot to add Peters start / wait in this image until later
You can't interact with Microsoft Excel (or most of other programs) through Batch unless they provide such an interface. There is however an option to do it with VBS i.e. via an interface Microsoft Excel supports for interacting with that software.
For just opening the program check start command e.g.:
start /B excel.exe <filename>
then you can wait for the user to both edit and save the file for two minutes or also utilize pause if you don't want to introduce a race condition between saving and copying with xcopy.
Alternatively use start like this:
start /WAIT /B excel.exe <filename>
so the opened file blocks the operation and once it closes (no edit or saving by the user guaranteed) then it'll unblock and xcopy would take place without any time-dependent feature.
When the script gets to the IF statement, it just ends. It doesn't go to the next line which is pause for debugging.
set yymm=%DATE:~12,2%%DATE:~4,2%
set DD=%DATE:~7,2%
robocopy "\\client system\Users\login name\Videos" "F:\Temporary\Videos\Process\New Batch\%yymm%%dd%\Netbook\Videos" /mir
set /p %user%=Did Netbook Videos complete? (y/n):
IF %user%=="y" (del "\\client system\Users\login name\Videos\"*.* /s/q) ELSE (echo Skipping)
I know that there is a /move switch for robocopy command. But it tells me that it doesn't have access to the destination folder. The batch program runs with administrative access and it is running in the profile that created the folder. So I wrote a workaround.
Why is this happening?
I recommend first to read following answers:
Debugging a batch file explains how to debug a batch file because of cmd.exe always outputs an error message on exiting execution of a batch file because of a syntax error as caused by your wrong code.
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
The answer on this question explains how to define and use environment variables correct on Windows.
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
The answer on this question explains in detail with examples the usage of set /P and choice whereby the latter is better for all user prompts on which the user must take one of the options the batch file offers during execution.
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
The question is really self-explaining.
The batch file below assumes that the string substitutions done with value of dynamic environment variable DATE works with used user account because of date format depends on which region/country/locale is set for used user account.
set "yymm=%DATE:~12,2%%DATE:~4,2%"
set "DD=%DATE:~7,2%"
%SystemRoot%\System32\robocopy.exe "\\client system\Users\login name\Videos" "F:\Temporary\Videos\Process\New Batch\%yymm%%dd%\Netbook\Videos" /mir
%SystemRoot%\System32\choice.exe /N /M "Did Netbook Videos complete? (y/n): "
if errorlevel 2 (echo Skipping) else del /S /Q "\\client system\Users\login name\Videos\*"
I suggest also reading How to delete files/subfolders in a specific directory at command prompt in Windows? The command DEL as used here does not delete all files and leaves behind subdirectories which are most likely empty after deleting most or by chance all video files. But it would be good to avoid deletion of hidden system file desktop.ini in videos directory of a user account which is usually referenced with %USERPROFILE%\Videos.
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.
choice /?
del /?
echo /?
if /?
robocopy /?
set /?
Thanks. Thought I'd try writing a batch file to kill another open cmd session that is constantly open churning out lots of scrolling info.
I got a bit carried away and am now outta my league so to speak.
Basically I am trying to search for "£000.00" within a each emerging line of tet that appears in the other running open command window. The running command session is named in the window as C:\windows\system32\cmd.exe but is does have a valid .exe process name in task manager while running and open.
The batch file code below is as far as I've got.
The idea is that when the above string is found in the other process that process/program get closed down them re-launched.
This is as far as I've got.
#echo off
#echo off
title Shut down other process and relaunch
:loop
start /d "C:\Users\Desktop" ActiveDOSprogram.exe
:: #setlocal enabledelayedexpansion
:: #echo off
:: set stringfound=1
find /c "*£000.00*" C:\Windows\system32\cmd.exe && (echo found %date% %time%:~0,-3% >> "%USERPROFILE%\Desktop\Crash_Report.txt"
taskkill /IM ActiveDOSprogram.exe /F
timeout /t 20
start /d "C:\Users\Desktop" ActiveDOSprogram.exe
goto loop
So when I tried this without any variables and in a loop and I think i nearly blew my PC!
Reason I'm stuck is I'm really a novice at this (but trying) and I got as far as I think I need a variable in there somewhere, that only move's to the next line (taskkill+restart) when £000.00 is found in the other process.
Thanks
wingman
The Windows command line interpreter features a FOR command, which is able to parse the output of a given command and execute the loop for each line of the output, e.g.:
FOR /F %%i IN ('DIR .') DO echo %i # Outputs each file name
The command (DIR .) is executed in a child command line via cmd /C <command> <command-arguments>, however, the /D parameter is not specified ... this leads to weird behavior if the user has a AutoRun command with output (e.g. echo, or cls).
Is there a way to force FOR to execute the command via cmd /C /D <command> <command-arguments>?
You have run across one of the many design flaws of cmd.exe, and this one has bothered me for quite some time. I'm pretty sure there is no way to suppress AutoRun when FOR /F executes a command.
What makes this especially irritating is that pipes also use CMD /C (one for each side of the pipe), but the designers of the pipe were smart enough to incorporate both the /D and /S options. It is really a shame the designers of FOR /F couldn't have done the same.
I believe your only recourse One option is to be defensive within your AutoRun command definition. I suggest putting all the AutoRun commands within a batch script that has something like the following at the top:
#echo off
if defined AutoRunComplete exit /b
set AutoRunComplete=1
REM Put your AutoRun commands below...
But if you cannot control the AutoRun commands, then I think you are out of luck. Aacini's idea of using a temporary file to get around the problem is an effective and simple solution.
A very simple solution for your problem is use a file in the for /F command instead of a command. This way, we just emulate the internal operation of for /F over a command, but executing each step explicitly: 1. Execute the command and store its output in a temporary text file. 2. Process all lines in the temporary file. 3. Delete the file.
DIR . > TempFile.txt
FOR /F %%i IN (TempFile.txt) DO echo %%i
DEL TempFile.txt
When you have many FOR /F blocks for parsing program output, then it could be useful to add a cmd.exe wrapper.
This wrapper can be installed with
set "comspec=C:\somewhere\cmdWrapper.exe"
FOR /F %%i IN ('DIR .') DO echo %%i
The wrapper itself has to start the original cmd.exe with /D /C.
But the behaviour of the comspec variable itself is a bit strange.
How to make .BAT file delete it self after completion? I have a simple bat file that terminates a process. I want that .BAT file to delete itself.
The Merlyn Morgan-Graham answer manages to delete the running batch script, but it generates the following error message: "The batch file cannot be found." This is not a problem if the console window closes when the script terminates, as the message will flash by so fast that no one will see it. But the error message is very undesirable if the console remains open after script termination.
John Faminella has the right idea that another process is needed to cleanly delete the batch file without error. Scheduling a task can work, but there is a simpler way: use START to launch a new delete process within the same console. It takes time for the process to initiate and execute, so the parent script has a chance to terminate cleanly before the delete happens.
start /b "" cmd /c del "%~f0"&exit /b
Update 2015-07-16
I've discovered another really slick way to have a batch script delete itself without generating any error message. The technique depends on a newly discovered behavior of GOTO (discovered by some Russians), described in English at http://www.dostips.com/forum/viewtopic.php?f=3&t=6491
In summary, (GOTO) 2>NUL behaves like EXIT /B, except it allows execution of concatenated commands in the context of the caller!
So all you need is
(goto) 2>nul & del "%~f0"
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
ECHO "This script will now self-destruct. Please ignore the next error message"
DEL "%~f0"
Note that the DEL line better be the last thing you intend to execute inside the batch file, otherwise you're out of luck :)
This will print out an ugly error message, but it is benign, and the code is slightly less confusing this way. If you care a lot about getting rid of the error message, see dbenham's answer to get rid of it.
You didn't mention the OS, but if this is on Windows XP Professional and you have the appropriate permissions, you can have the batch file schedule a one-shot Windows Scheduled Task to delete the file at a later time. Use the schtasks command, documented here.
Otherwise, you typically can't delete a file that is being executed, since that has the potential for all sorts of nastiness. Additionally, trying to delete an executable in use is viewed as very suspicious behavior by any number of antivirus programs, so it's likely that you would run afoul of these as well.
Just add this command at the last line of your batch file
Del batch_file_name.bat
batch_file_name.bat is the name of your batch file
Cheers
you could do #Merlyn's aswer
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
DEL "%~f0"
Now make a vbscript with this coding and save it as hidden.vbs, this vbscript will hide the batch file's window.
set w = CreateObject(“WScript.Shell”)
W.Run chr(34) & “%userprofile%\desktop\the_batch_file.bat” & chr(34), 0
set w= Nothing
Then have the batch file run this vbscript
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
start "path to hidden.vbs"
DEL "%~f0"
This will hide the batch file before deleting it making the error message impossible to see.
Inline next command to do the "last things" as ghost self. It can be the exit command or some other things before exiting.
#echo off
del "%~f0" && echo All's done. I must exit! && pause > nul && exit
You could also direct the output of the DEL "%~f0" to NULL output like so...
#ECHO OFF
SETLOCAL
SET someOtherProgram=SomeOtherProgram.exe
TASKKILL /IM "%someOtherProgram%"
DEL "%~f0" > NUL