Execute Batch File With Different Process Name - windows

I have 6 different batch scripts that I am running together at the same time. The problem is, it is difficult to differentiate between them in the Windows Task Manager because the process is always just cmd.exe I was wondering if there was a way to change the process name for a batch script to something else so that each script would be more identifiable.
I have done a lot of research on this topic so far, and the only lead that I have is creating a copy of cmd.exe in system32 that has a different name, one of my choosing. The problem is, I am not sure how I would get my bash script to use this new executable with a different name, rather than the default cmd.exe
Requirement: Must use only built in Windows functionality. I do not want to install any other programs if possible.

You can do it with something like the subroutine below. The reason for the first goto is so that you don't fall into the subroutine when you are done. I incorporate another FOR loop to iterate through a list of filenames to check. Let's get this working first.
Your existing bat file goes here
CALL :IsitRunning "SomeFileName"
The rest of your existing bat file goes here
GOTO :eof
:IsitRunning
REM 1=Filename
FOR /F "delims=" %%A in ('WMIC PROCESS WHERE NAME^='CMD.EXE' LIST FULL ^| FINDSTR /I "%~1" ^| FINDSTR /I /V WMIC') DO ECHO(%~1 is running
GOTO :eof
Or you can run this command from a CMD prompt.
wmic process WHERE NAME='cmd.exe' list full | findstr /i "SomeFileName.bat"

You can see command line in Task Manager, turn it on View menu - Choose Columns.
If you want to change process name you have to change the process. So your approach is only way.

Related

Start a command and if it doesn't work start another

I want to start acrobat from my software.
At this moment I'm using the following command:
cmd /c start AcroRd32.exe /t filename
But now acrobat sometimes updates to 64 bit version and then AcroRd32.exe doesn't exists anymore.
So we have to start acrobat.exe instead:
cmd /c start acrobat.exe /t filename
But we are working with a lot of clients with different computers and maybe different versions of acrobat. That is also why we don't specify an install path.
So is there a way to say in one command line entry (not a script) to start AcroRd32.exe and if this doesn't work start immediately acrobat.exe instead?
So something like:
cmd /c start AcroRd32.exe /t filename | if not 1 is ok then cmd /c start acrobat.exe /t filename
#ECHO OFF
SETLOCAL
FOR /f "delims=" %%b IN ('where autoruns64.exe autorunsc64.exe 2^>nul') DO CMD /c START "" "%%b" &GOTO done
ECHO NOT found!
:done
GOTO :eof
Note: START command : extra pair of quotes. This sets the title of the STARTed session, otherwise the first "quoted string" is used.
"%%b" is used in case the path to the executable (I used autoruns) contains a space.
The first argument to where is the preferred target.
where examines the path for filenames matching its arguments and lists them. The for /f reads the list and on the first match found, executes the START. If no match is found,an error message is produced by WHERE, which is suppressed by the 2^>nul.
Edit: one-line version
FOR /f "delims=" %b IN ('where autoruns64.exe autorunsc64.exe 2^>nul') DO CMD /c START "" "%b" &exit
Posted as a batch file because it's easier to re-run during testing.
WHERE locates files on the PATH and lists them
START locates files on the PATH and executes the first one found.
The PATH is the list of directories that will be examined by START, in the order in which they will be searched for the required executable, so WHERE examines that list of directories for the target executable, it does not search all of the drives in the hope of finding it.
Traditionally even on 64bit it was still Acrord32 for the free reader to avoid such dual name problems / complication and the 32bit or 64bit full product was start Acrobat.exe
However Adobe did not help by using version specifics within the registry so a query there would generally produce differing results ! Microsoft start adding enhancements as to where or how simple launchers may be deployed so the location now gets cloudier (pun :-)
However the traditional ask the registry works best except for my portable
version (where /r h:\ acrord32.exe is very slow on a TB drive and it was not on that one anyway, it was on a network drive!).
Simplest way I can think of via cmd to find an installed copy is:-
cmd /v:on /c "where acro*.exe>temp.txt&&set /p acroexe=<temp.txt&&if exist !acroexe! (!acroexe! /t %filename%)"
there is little use of errorlevel since the fail will simply report
> INFO: Could not find files for the given pattern(s).
Priority will be the first match within %path%
You also need to consider where temp.txt will be written perhaps "%tmp%\delme.txt"
Potential "Gotcha" is if first match finds something like AcrobatUpdater.exe
To avoid random acro's best use
cmd /v:on /c "where /f acrord32.exe acrobat.exe>temp.txt&&set /p acroexe=<temp.txt&&if exist !acroexe! (!acroexe! /t %filename%)"
actually since all you desire is start one or the other then
start "Reader" acrord32.exe /t "filename.pdf" "printer name"||start "Editor" acrobat.exe /t "filename.pdf" "printer name"
The downside to this last method is Windows will raise a GUI error if acrord32 cannot "start" Thus gui warning needs to be dismissed before the second option can be run and start. In that case START cannot be told to be silent on error.
Finally make your choice from above or use a hybrid approach
where /f acrord32.exe... || start acrobat.exe.. will not warn user on first fail but only on second if both missing.

Batch script, call cmd on servers

I am trying to call x.cmd from many servers in a list and basically x.cmd will return a log file so I will copy the output log files into a new folder.
the structure in that list is:
server name&folder path of the x.cmd on thet server&output folder name that I will create
when I run the script below, it doesn't return any error and return value is 0. but x.cmd just doesn't do anything when I check on the actual server. x.cmd working fine once I run it manually.
Please if possible point me out the mistake of my script. my other concern is the folder path being too long(but it is within the limits of Microsoft if I am right). :) Thanks for your time.
#echo on
cd /d %~dp0
setlocal EnableDelayedExpansion
set serverList=List.txt
for /f "usebackq tokens=1,2,3* delims=&" %%A in ("%serverList%") DO (
set remoteCmd=x.cmd
wmic /node:%%A process call create "%%B\remoteCmd"
pause
robocopy %%B\logs Output\%%C /e
)
endlocal
Pause
JS
The problem seems to be that you're not actually calling x.cmd on the remote servers, since the variable isn't substituted in the wmic call. Move the definition of remoteCmd out of the loop and enclose remoteCmd in the wmic call in percent signs:
set serverList=List.txt
set remoteCmd=x.cmd
for /f "usebackq tokens=1,2,3* delims=&" %%A in ("%serverList%") DO (
wmic /node:%%A process call create "%%B\%remoteCmd%"
pause
robocopy %%B\logs Output\%%C /e
)
Update 1: Since you're getting a response on the shell with a processID and Error level=0, it's fairly safe to say that x.cmd was in fact started on the remote server. The fact that the logfile does not turn up in the same directory where x.cmd resides in, is very probably because the logfile is not given an absolute path in x.cmd. That means it will be created in the directory on the remote machine where the cmd.exe is located, which is executing x.cmd. In most systems this will be %WINDIR%\system32, i.e. c:\windows\system32.
Update 2: If modifying x.cmd is no option, then you need to change the path to it's directory before calling it. You can do it like this:
wmic /node:%%A process call create "cmd /c cd /d %%B & x.cmd"
Note: The cd /d allows you to change directories even across different drives.
Update 3: Since there are spaces in the directory names you'll need to enclose them with quotes - which will have to be escaped, since there already outer quotes enclosing the whole remote command. So that means:
wmic /node:%%A process call create "cmd /c \"cd /d %%B\" & x.cmd"
Note: A possible alternative to the inner quotes would be to use 8.3-filenames of the involved directories. You can view those with dir /x on the command line.

Running Multiple Installations with System-Reboot Inbetween them

Currently I have a set of software-Installations(and their paths) that i have to install on my Windows Machine.
What I do now is -- Hit RUN every time and type in the software installation path into it..
What I want is to design a Batch file which would install all the applications and REBOOT my system after every successful installation and then continue with the NEXT item in the list..
Is it possible using a .bat file ??
This really isn't something batch was designed for, so this will be a bit hacky. It's not elegant by any means but give it a shot, it might work for you.
for /f %%a in (C:\files.txt) do (
start /wait %%a
exit /b
)
for /f "skip=1" %%b in ("C:\files.txt) do (
echo %%b >>C:\newfiles.txt
)
xcopy C:\newfiles.txt C:\files.txt /y
del C:\newfiles.txt /f /q
shutdown /r /t 0 /f
The idea being that you have a text file with the paths of the executables that you want to install. It will go through and execute the first file in the list, wait for it to complete, then re-write the list without the file it just installed.
This is dependend on the setup file having no user interaction and exiting by itself, or maybe it's just to make things easier - in which case just go through each install yourself, and when it finishes the batch file will do the rest.
On the note of rebooting and continuing you will either need to run the batch file again yourself or put it in the registry to start up itself, the latter command being
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v "MyBatchInstaller" /d "C:\MyBatchFile.bat" /f
Hope this helps

pipe multiple files into a single batch file (using explorer highlight)

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

Detecting how a batch file was executed

Assuming Windows, is there a way I can detect from within a batch file if it was launched from an open command prompt or by double-clicking? I'd like to add a pause to the end of the batch process if and only if it was double clicked, so that the window doesn't just disappear along with any useful output it may have produced.
Any clever ways to do this? I'm looking for solutions I could rely on to work on a machine that was configured more or less with default settings.
I just ran a quick test and noticed the following, which may help you:
When run from an open command prompt, the %0 variable does not have double quotes around the path. If the script resides in the current directory, the path isn't even given, just the batch file name.
When run from explorer, the %0 variable is always enclosed in double quotes and includes the full path to the batch file.
This script will not pause if run from the command console, but will if double-clicked in Explorer:
#echo off
setlocal enableextensions
set SCRIPT=%0
set DQUOTE="
#echo do something...
#echo %SCRIPT:~0,1% | findstr /l %DQUOTE% > NUL
if %ERRORLEVEL% EQU 0 set PAUSE_ON_CLOSE=1
:EXIT
if defined PAUSE_ON_CLOSE pause
EDIT:
There was also some weird behavior when running from Explorer that I can't explain. Originally, rather than
#echo %SCRIPT:~0,1% | findstr /l %DQUOTE% > NUL
if %ERRORLEVEL% EQU 0 set PAUSE_ON_CLOSE=1
I tried using just an if:
if %SCRIPT:0,1% == ^" set PAUSE_ON_CLOSE=1
This would work when running from an open command prompt, but when run from Explorer it would complain that the if statement wasn't correct.
Yes. Patrick Cuff's final example almost worked, but you need to add one extra escape, '^', to make it work in all cases. This works great for me:
set zero=%0
if [^%zero:~0,1%] == [^"] pause
However, if the name of the batch file contains a space, it'll be double quoted in either case, so this solution won't work.
Don't overlook the solution of having two batch files:
abatfile.bat and abatfile-with-pause.bat
The second simply calling the first and adding a pause
Here's what I use :
rem if double clicked it will pause
for /f "tokens=2" %%# in ("%cmdcmdline%") do if /i "%%#" equ "/c" pause
I use a parameter "automode" when I run my batch files from scripts.
set automode=%7
(Here automode is the seventh parameter given.)
Some code follows and when the file should pause, I do this:
if #%automode%==# pause
One easy way to do it is described here:
http://steve-jansen.github.io/guides/windows-batch-scripting/part-10-advanced-tricks.html
There is little typo in the code mentioned in the link. Here is correct code:
#ECHO OFF
SET interactive=0
ECHO %CMDCMDLINE% | FINDSTR /L /I %COMSPEC% >NUL 2>&1
IF %ERRORLEVEL%==0 SET interactive=1
ECHO do work
IF "%interactive%"==1 PAUSE
EXIT /B 0
Similar to a second batch file you could also pause if a certain parameter is not given (called via clicking).
This would mean only one batch file but having to specify a -nopause parameter or something like that when calling from the console.
crazy idea: use tasklist and parse it's results.
I've wrote in a test batch file:
tasklist > test.out
and when I double-clicked it, there was an additional "cmd.exe" process just before the tasklist process, that wasn't there when the script was run from command line (but note that might not be enough if someone opens a command line shell and then double-click the batch file)
Just add pause regardless of how it was opened? If it was opened from command prompt no harm done apart from a harmless pause. (Not a solution but just thinking whether a pause would be so harmful / annoying )

Resources