Positioning CMD Window

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Positioning CMD Window

#1 Post by abc0502 » 09 Feb 2013 20:26

In order to Position the cmd window to a specific location, you must change the registry setting, then when you are done, you need then to reset the registry settings.

Another way, is by using this vbscript i found on the Internet.

Code: Select all

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set objConfig = objWMIService.Get("Win32_ProcessStartup")
objConfig.SpawnInstance_
objConfig.X = 350
objConfig.Y = 350
Set objNewProcess = objWMIService.Get("Win32_Process")
intReturn = objNewProcess.Create("C:\Documents and Settings\admin\desktop\Fixed_location.bat", Null, objConfig, intProcessID)
as you can see objConfig.X and objConfig.Y where you set the X & Y Coordinates, and the location of the batch File in intReturn

By this you can position any batch file window by setting it's X and Y Coordinates,

But This will require Two Files, Batch File and VBscript,
you can make it in one file by creating two functions "labels" one to create the VBscript and one to create the Batch File but then you will have to escape every (, ), > , & characters in your code and if it a big code that will be a waste of time, so to avoid that here is a work around:

> First, you make a start code or "header", this 3 lines any batch you want to set it's coordinate must start with,
> Then, in the code section put your batch file codes, and don't forget the label ":Code"
> Create a function that create only the vbscript, which you call it in the 2nd command in our "header"
AND Make Sure BEFORE your batch file end, YOU MUST DELETE the vbscript. so add a delete command to your code to delete the vbscript you created in the "header"

This is a Sample, will set the position to 350 and 350 (X,Y) Coordinates.

Code: Select all

@Echo OFF

REM ===== Header ====================================
REM == MUST BE AT The Begining of The Batch =========
   IF EXIST "%temp%\pos.vbs" Goto :Code
   CALL :Pos "350" "350"                 %= [350 350] is X, Y Coordinate =%
   EXIT /B



REM ===== Code ======================================
REM == Put All Your Code Down Here ==================
:Code
Echo This is a Test Batch File in 350, 350 Coordinates on the screen
Pause

REM == MUST Delete The Vbscript before Your Batch Ends
DEL /Q "%temp%\Pos.vbs"
Exit /B


REM ===== Position Script============================
:Pos <X_Coordinate> <Y_Coordinate>
REM This Function will take two inputs X and Y Coordinates to Position the CMD window
REM %~dpnx0 in the script will get this batch full path and add it
REM         to the vbscript, so the vbscript run the batch in position.
(
Echo Set objWMIService = GetObject^("winmgmts:\\.\root\cimv2"^)
Echo Set objConfig = objWMIService.Get^("Win32_ProcessStartup"^)
Echo objConfig.SpawnInstance_
Echo objConfig.X = %~1
Echo objConfig.Y = %~2
Echo Set objNewProcess = objWMIService.Get^("Win32_Process"^)
Echo intReturn = objNewProcess.Create^("%~dpnx0", Null, objConfig, intProcessID^)
)>"%temp%\pos.vbs"
Start "" "%temp%\pos.vbs"
Goto :EOF
The Pos label here, i made it take 2 arguments, X and Y Coordinates, you can put the coordinates directly in the vbscript.

Edited
Final Note:
This has a problem, because if your batch file was interrupted or crashed and didn't exit in the right way, the vbscript will not be deleted and then when you run the batch again it won't be positioned in the right coordinates you have set.

:oops: There is a fix for that,
You can delete the VBscript at the beginning of your batch code "in code section",
So even if your batch didn't work from the beginning and crashed, the first thing to do is to delete the vbscript,
I think this should solve it.

The Code section should be something like that :
REM ===== Code ======================================
REM == Put All Your Code Down Here ==================
:Code
REM == MUST Delete The Vbscript First
DEL /Q "%temp%\Pos.vbs"
Echo This is a Test Batch File in 350, 350 Coordinates on the screen
Pause
Exit /B

REM ===== Position Script============================
.
.
.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Positioning CMD Window

#2 Post by Aacini » 09 Feb 2013 21:06

A much simpler way to do that (and more) is using my Window.exe auxiliary program; for example:

Code: Select all

rem Position Window at 350,350
Window GPos 350 350

This is the usage of Window.exe auxiliary program:
Window.exe description wrote:Get or set some values related to console screen window.

Window
Show the window title.

Window Size [width height]
Set window size in characters.
At end, previous window size is returned as width+(height<<16) in ERRORLEVEL.

Window GSize [MIN|MAX|REST|HIDE|SHOW]
Set window graphic size or show state.
At end, previous window client-area size in pixels is returned as width+(height<<16) in ERRORLEVEL.

Window GPos [x y]
Set window position in pixels.
At end, return previous window position in pixels as x+(y<<16) in ERRORLEVEL.

At that post there is an example program that allows to change Window size with arrow keys, move Window in pixel steps with Alt-arrow key, and move Window in character-wide steps with Ctrl-arrow keys (I like it! :D ).

Antonio

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#3 Post by abc0502 » 09 Feb 2013 21:34

Thanks Aacini, I always forget about your topic :)
it has a nice tools.
but isn't that will require external files, though we can use the Bhx tool, carols made, to include the exe in the batch file.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Positioning CMD Window

#4 Post by Aacini » 13 Feb 2013 23:47

I carefully reviewed your code and found several funny details! The usual way to reuse a code section is via parameters, but you made a copy of the code with static values in place of parameters, so the copied code just work for the copied values. I made a Google search for "VBScript Parameters" and the first page found indicate this:
Sweet VBScript – command line parameters wrote:You can access the command line arguments array through

WScript.Arguments(i)

where i goes from 0 upwards.
This way, to provide variable Window positions to the same VBScript code you may use:

Code: Select all

objConfig.X = WScript.Arguments(1)
objConfig.Y = WScript.Arguments(2)
This method avoid the need to delete the pos.vbs file each time the Batch file run (more on this point later).

There are several ways to write VBS code inside a Batch file. Dave and jeb had shown us a couple advanced (and confusing!) methods to achieve this, but perhaps the simplest method is prefix VBS lines with an unique string so they can be directly extracted with a FINDSTR command. This way, you don't need to worry about special Batch characters in VBS code.

Let's see now the tricky part! I run your code and confirmed that it correctly works: a new window appear in top-left corner of the screen and one instant later the window is moved to a new position. However, I didn't understood how the code works even I reviewed it for several minutes. Finally, I realized that the VBScript code does NOT move the existent window to a new place, but it EXECUTE the Batch file again placing the new CMD window in another position instead! In order for this to work, the original (executed first time) Batch code must terminate as soon as it run the VBS script, but instead of just run it in a simple way: "%temp%\pos.vbs", your code use a START command to create a visual effect to fool the user into thinking that the original window was moved.

As I said before, using arguments in VBS code allows to use the same code for any window position and avoids the need to delete the .VBS file each time the Batch file run. However, your code use the existence of the VBS file as indication of the run phase of the Batch file: command-line started phase (file not exist), or restarted phase from VBS code (file exist); this may cause problems if the Batch code is cancelled before the VBS file is deleted, as you explained before. I used a different method to identify the run phase of the Batch file based on a parameter; you may review an example of this method in While macro This is my final version of your code:

Code: Select all

@Echo OFF

REM ===== Header ====================================
REM == MUST BE AT The Begining of The Batch =========
   IF "%~1" == "RestartedByVBS" Goto :Code

   REM Create the VBScript, if not exist
   IF NOT EXIST "%~DP0pos.vbs" (
      (FOR /F "tokens=1*" %%a in ('findstr "^VBS:" ^< "%~F0"') do (
         echo(%%b
      )) > "%~DP0pos.vbs"
   )
   REM Start "" "%~DP0pos.vbs" "%~F0" 350 350
   Cscript //nologo "%~DP0pos.vbs" "%~F0" 350 350
   EXIT /B



REM ===== Code ======================================
REM == Put All Your Code Down Here ==================
:Code
Echo This is a Test Batch File in 350, 350 Coordinates on the screen
Pause

Exit /B


REM ===== Position Script============================

:Pos <BatchFileName> <X_Coordinate> <Y_Coordinate>

REM This Function will take three inputs: the name of the Batch file to execute
REM and the X and Y Coordinates to Position its CMD window

VBS: Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
VBS: Set objConfig = objWMIService.Get("Win32_ProcessStartup")
VBS: objConfig.SpawnInstance_
VBS: objConfig.X = WScript.Arguments(1)
VBS: objConfig.Y = WScript.Arguments(2)
VBS: Set objNewProcess = objWMIService.Get("Win32_Process")
VBS: intReturn = objNewProcess.Create(WScript.Arguments(0)&" RestartedByVBS", Null, objConfig, intProcessID)

REM ===== End of VBScript============================


Antonio

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#5 Post by abc0502 » 14 Feb 2013 00:33

I have to say this is very clever way to check how the batch was started, really very clever :o

I only know few about VBscript and how it is constructed,
I just can combine pieces together and with a few search in google i can come with the correct answer, so i was just passing the values to it when creating it.

However, i never thought about passing the parameters that way i guess i change all my code snippets that contain vbscript to take parameters instead of static values :lol: , that will make it easier than overwriting files over and over. :wink:

And about:
Let's see now the tricky part! I run your code and confirmed that it correctly works: a new window appear in top-left corner of the screen and one instant later the window is moved to a new position. However, I didn't understood how the code works even I reviewed it for several minutes. Finally, I realized that the VBScript code does NOT move the existent window to a new place, but it EXECUTE the Batch file again placing the new CMD window in another position instead! In order for this to work, the original (executed first time) Batch code must terminate as soon as it run the VBS script, but instead of just run it in a simple way: "%temp%\pos.vbs", your code use a START command to create a visual effect to fool the user into thinking that the original window was moved.
well, I never meant to do that in purpose even i didn't meant it to be as an effect, all what i wanted two files in one instead of using two files . :D

That will be very helpful in the future and thanks for the code too :lol:
Thanks, I really appreciate it.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#6 Post by abc0502 » 14 Feb 2013 01:06

but perhaps the simplest method is prefix VBS lines with an unique string so they can be directly extracted with a FINDSTR command.

I didn't understand that when i read your post at the first but this is really clever, i also read before here or on another site a way to run the vbscript from the batch file without creating any extra file, i didn't understood it but it was impressive.

BTW, The batch just hang and doesn't produce the vbscript, it create empty file and only an empty cmd window remain on the screen.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Positioning CMD Window

#7 Post by foxidrive » 14 Feb 2013 01:30

The file probably doesn't have an ending CR/LF. Use FIND instead for these cases, or add a trailing CR/LF

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#8 Post by abc0502 » 14 Feb 2013 02:53

Thanks Foxidrive, it's now create the vbscript but the vbscript itself doesn't start the batch file.
it just blink and exit right away.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#9 Post by abc0502 » 14 Feb 2013 03:32

After Few tests, There is nothing passed to the batch file.
Add This two lines to the batch file after @Echo off

Code: Select all

Echo %~1
Pause

and the result is "ECHO is off"

Also after adding this line to see what is being passed to the vbscript, i get the right values but it still don't work, just open very fast and close.

Code: Select all

VBS: Wscript.Echo WScript.Arguments(0), WScript.Arguments(1), WScript.Arguments(2)

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Positioning CMD Window

#10 Post by foxidrive » 14 Feb 2013 04:06

If I delete the vbs file with this before the creation it works.

Add the blue line.

REM Create the VBScript, if not exist
del "%~DP0pos.vbs" 2>nul

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#11 Post by abc0502 » 14 Feb 2013 04:11

Still blink and exit quickly, beside Aacini code is based on avoiding overwriting the vbscript file.
but if it work with you and with Aacini it must be something wrong with my computer i will try to restart the pc

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Positioning CMD Window

#12 Post by foxidrive » 14 Feb 2013 04:26

Try this. I've had erratic failures from this but now it works - I don't think there are any changes.

Make sure the last line is empty in the batch file.

Code: Select all

@Echo OFF

REM ===== Header ====================================
REM == MUST BE AT The Begining of The Batch =========
   IF "%~1" == "RestartedByVBS" Goto :Code

   REM Create the VBScript, if not exist
   IF NOT EXIST "%~DP0pos.vbs" (
      (FOR /F "tokens=1*" %%a in ('findstr "^VBS:" ^< "%~F0"') do (
         echo(%%b
      )) > "%~DP0pos.vbs"
   )
   REM Start "" "%~DP0pos.vbs" "%~F0" 350 350
   Cscript //nologo "%~DP0pos.vbs" "%~F0" 350 350
   EXIT /B



REM ===== Code ======================================
REM == Put All Your Code Down Here ==================
:Code
Echo This is a Test Batch File in 350, 350 Coordinates on the screen
Pause

Exit /B


REM ===== Position Script============================

:Pos <BatchFileName> <X_Coordinate> <Y_Coordinate>

REM This Function will take three inputs: the name of the Batch file to execute
REM and the X and Y Coordinates to Position its CMD window

VBS: Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
VBS: Set objConfig = objWMIService.Get("Win32_ProcessStartup")
VBS: objConfig.SpawnInstance_
VBS: objConfig.X = WScript.Arguments(1)
VBS: objConfig.Y = WScript.Arguments(2)
VBS: Set objNewProcess = objWMIService.Get("Win32_Process")
VBS: intReturn = objNewProcess.Create(WScript.Arguments(0)&" RestartedByVBS", Null, objConfig, intProcessID)

REM ===== End of VBScript============================


abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#13 Post by abc0502 » 14 Feb 2013 04:32

still not working, i used the method Aacini used to pass parameters to the vbscript, and applied it to my original code, and i had the same result, it must be something related to "WScript.Arguments()"

Edited:
I think i know what is going wrong, I bet Aacini was testing on his C:\ or D:\ drive right a way.
I tried to read what appear before the window close it give the error that appears when you try to use a path name that contain spaces somthing like "C:\Documents" can't be recognized as ..... etc.

It seams that WScript.Arguments() behave like %~1 and remove the double quotes from around the Path name as i test on my desktop, but when testing on C:\ or D:\ directly or a path with no spaces it work fine.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Positioning CMD Window

#14 Post by abc0502 » 14 Feb 2013 04:44

OK, Here is the fix, using char(34) like this:

Code: Select all

VBS: intReturn = objNewProcess.Create( chr(34) & WScript.Arguments(0) &chr(34)& " RestartedByVBS", Null, objConfig, intProcessID)
The last line should be like this, The quotes is represented as char(34) and the & is used to join characters. now it's working :D :D

and credits goes to : Link

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Positioning CMD Window

#15 Post by foxidrive » 14 Feb 2013 05:06

I was also using a path with no spaces

Ta.

Post Reply