I have an application which starts at position 0x0 of my desktop. I want to open it in the center of my desktop. I do not want to open it and use a move command to move it into center, instead my app should start immediately at center position.
Is there any way to do this via command prompt?
You'll need an additional utility such as cmdow.exe to accomplish this. Look specifically at the /mov switch. You can either launch your program from cmdow or run it separately and then invoke cmdow to move/resize it as desired.
Have found that AutoHotKey is very good for window positioning tasks.
Here is an example script. Call it notepad.ahk and then run it from the command line or double click on it.
Run, notepad.exe
WinWait, ahk_class Notepad
WinActivate
WinMove A,, 10, 10, A_ScreenWidth-20, A_ScreenHeight-20
It will start an application (notepad) and then adjust the window size so that it is centered in the window with a 10 pixel border on all sides.
I just found this question while on a quest to do the same thing.
After some experimenting I came across an answer that works the way the OP would want and is simple as heck, but not very general purpose.
Create a shortcut on your desktop or elsewhere (you can use the create-shortcut helper from the right-click menu), set it to run the program "cmd.exe" and run it. When the window opens, position it where you want your window to be. To save that position, bring up the properties menu and hit "Save".
Now if you want you can also set other properties like colors and I highly recommend changing the buffer to be a width of 120-240 and the height to 9999 and enable quick edit mode (why aren't these the defaults!?!)
Now you have a shortcut that will work. Make one of these for each CMD window you want opened at a different location.
Now for the trick, the windows CMD START command can run shortcuts. You can't programmatically reposition the windows before launch, but at least it comes up where you want and you can launch it (and others) from a batch file or another program.
Using a shortcut with cmd /c you can create one shortcut that can launch ALL your links at once by using a command that looks like this:
cmd /c "start cmd_link1 && start cmd_link2 && start cmd_link3"
This will open up all your command windows to your favorite positions and individually set properties like foreground color, background color, font, administrator mode, quick-edit mode, etc... with a single click. Now move that one "link" into your startup folder and you've got an auto-state restore with no external programs at all.
This is a pretty straight-forward solution. It's not general purpose, but I believe it will solve the problem that most people reading this question are trying to solve.
I did this recently so I'll post my cmd file here:
cd /d C:\shortucts
for %%f in (*.lnk *.rdp *.url) do start %%f
exit
Late EDIT: I didn't mention that if the original cmd /c command is run elevated then every one of your windows can (if elevation was selected) start elevated without individually re-prompting you. This has been really handy as I start 3 cmd windows and 3 other apps all elevated every time I start my computer.
This probably should be a comment under the cmdow.exe answer, but here is a simple batch file I wrote to allow for fairly sophisticated and simple control over all windows that you can see in the taskbar.
First step is to run cmdow /t to display a list of those windows. Look at what the image name is in the column Image, then command line:
mycmdowscript.cmd imagename
Here are the contents of the batch file:
:: mycmdowscript.cmd
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET IMAGE=%1
SET ACTION=/%2
SET REST=1
SET PARAMS=
:: GET ANY ADDITIONAL PARAMS AND STORE THEM IN A VARIABLE
FOR %%I in (%*) DO (
IF !REST! geq 3 (
SET PARAMS=!PARAMS! %%I
)
SET /A REST+=1
)
FOR /F "USEBACKQ tokens=1,8" %%I IN (`CMDOW /t`) DO (
IF %IMAGE%==%%J (
:: you now have access to the handle in %%I
cmdow %%I %ACTION% !PARAMS!
)
)
ENDLOCAL
#echo on
EXIT /b
example usage
:: will set notepad to 500 500
mycmdowscript.cmd notepad siz 500 500
You could probably rewrite this to allow for multiple actions on a single command, but I haven't tried yet.
For this to work, cmdow.exe must be located in your path. Beware that when you download this, your AV program might yell at you. This tool has (I guess) in the past been used by malware authors to manipulate windows. It is not harmful by itself.
You can use nircmd project here: http://www.nirsoft.net/utils/nircmd.html
Example code:
nircmd win move ititle "cmd.exe" 5 5 10 10
nircmd win setsize ititle "cmd.exe" 30 30 100 200
nircmd cmdwait 1000 win setsize ititle "cmd.exe" 30 30 1000 600
If you are happy to run a batch file along with a couple of tiny helper programs, a complete solution is posted here:
How can a batch file run a program and set the position and size of the window? - Stack Overflow (asked: May 1, 2012)
Bill K.'s answer was the most elegant if you just want to start a window at startup or start from a shortcut on the desktop.
Just open the window where you want it,
right click and choose properties.
select Layout
uncheck "let system position window"
and click OK.
Window will now open just where you want it.
You can set font and window colors at the same time on other tabs.
sweet.
Thanks To FuzzyWuzzy , set the following code ( Quick & Dirty Example for 1920x1080 screen resolution - without automatic width and height calculation or function use etc ) in AutoHotKey
to achive the following :
v_cmd = c:\temp\1st_Monitor.ps1
Run, Powershell.exe -executionpolicy remotesigned -File %v_cmd%
SetTitleMatchMode 2
SetTitleMatchMode Fast
WinWait, PowerShell
Sleep, 1000
;A = Active window - [x,y,width,height]
WinMove A,, 0, 0,1920,500
v_cmd = c:\temp\2nd_Monitor.ps1
Run, Powershell.exe -executionpolicy remotesigned -File %v_cmd%
WinWait, PowerShell
Sleep, 1000
;A = Active window - [x,y,width,height]
WinMove A,, 0, 500,960,400
v_cmd = c:\temp\3rd_Monitor.ps1
Run, Powershell.exe -executionpolicy remotesigned -File %v_cmd%
WinWait, PowerShell
Sleep, 1000
;A = Active window - [x,y,width,height]
WinMove A,, 960, 500,960,400
SMALL EDIT
same code with Auto X / Y screen size calculation [ 4 monitors ], yet, can be used for 3 / 2 monitors as well.
Screen_X = %A_ScreenWidth%
Screen_Y = %A_ScreenHeight%
v_cmd = c:\temp\1st_Monitor.ps1
Run, Powershell.exe -executionpolicy remotesigned -File %v_cmd%
SetTitleMatchMode 2
SetTitleMatchMode Fast
WinWait, PowerShell
Sleep, 1000
;A = Active window - [x,y,width,height]
WinMove A,, 0, 0,Screen_X/2,Screen_Y/2
v_cmd = c:\temp\2nd_Monitor.ps1
Run, Powershell.exe -executionpolicy remotesigned -File %v_cmd%
WinWait, PowerShell
Sleep, 1000
;A = Active window - [x,y,width,height]
WinMove A,, Screen_X/2, 0,Screen_X/2,Screen_Y/2
v_cmd = c:\temp\3rd_Monitor.ps1
Run, Powershell.exe -executionpolicy remotesigned -File %v_cmd%
WinWait, PowerShell
Sleep, 1000
;A = Active window - [x,y,width,height]
WinMove A,, 0, Screen_Y/2,Screen_X/2,Screen_Y/2
v_cmd = c:\temp\4th_Monitor.ps1
Run, Powershell.exe -executionpolicy remotesigned -File %v_cmd%
WinWait, PowerShell
Sleep, 1000
;A = Active window - [x,y,width,height]
WinMove A,, Screen_X/2, Screen_Y/2,Screen_X/2,Screen_Y/2
I too wanted to do this and came across this thread: Positioning CMD Window. No external files to download as it creates a small bit of VBScript on the fly to do all the lifting. All you need to do is specify your X & Y coordinates in the following section: Cscript //nologo "%~DP0pos.vbs" "%~F0" 100 50. The .vbs script is also removed after it has been executed too so there is no need to tidy anything up.
Place this at the top of your batch file:
REM - Position the CMD Window Using .VBS -----------------------------------------
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" 100 50
Cscript //nologo "%~DP0pos.vbs" "%~F0" 100 50
EXIT /B
:code
DEL /Q "%~DP0pos.vbs"
REM ------------------------------------------------------------------------------
PLACE THE CONTENTS OF YOUR OWN BATCH FILE HERE
And this at the bottom:
REM - Position the CMD Window Using .VBS -----------------------------------------
: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( chr(34) & WScript.Arguments(0) &chr(34)& " RestartedByVBS", Null, objConfig, intProcessID)
REM ------------------------------------------------------------------------------
Enjoy :)
Related
I am troubleshooting a problem with a device keeping a Windows 10 PC awake using the powercfg -requests command. I have a BAT file containing the following so it can be run quickly via shortcut with run as admin properties:
cmd /k powercfg -requests
This works, but in addition to keeping the window open, I'd like to be able to keep sending powercfg -requests by hitting arrow up/enter when needed, as would normally happen if I opened a command prompt and typed it manually.
I've searched quite a bit here, and aside from making it repeat automatically,
I haven't found anything other than sending arrow keystrokes in a BAT file.
I did see something which implied it might be possible to print the command so it's entered at the prompt
after the command has executed, which would be fine too, but haven't had much luck.
Is this possible?
Sorry, there is not a simple way...
This works:
#if (#CodeSection == #Batch) #then
#echo off
start "" /B cmd /K
timeout /T 1
CScript //nologo //E:JScript "%~F0" "powercfg -requests{ENTER}"
goto :EOF
#end
WScript.CreateObject("WScript.Shell").SendKeys(WScript.Arguments(0));
For a further description on the method used, see this answer
Use PowerShell instead. You can right click on Desktop > New Shortcut and paste this then save
powershell -NoExit -Command "Add-Content -Path (Get-PSReadlineOption).HistorySavePath 'powercfg -requests'; Invoke-Expression 'powercfg -requests'"
It's better to create a new shortcut because you can set it to always run as admin although it's still possible to put it in a *.bat/*.ps1 file
You can also shorten it like this
powershell -NoE -C "$c = 'powercfg -requests'; ac (Get-PSReadlineOption).HistorySavePath $c; iex $c"
PowerShell is far more flexible and powerful than batch. It also has a persistent history so it's far more convenient to use PowerShell. You may not even need this and just press Ctrl+R to search through history for the powercfg command just like in bash/zsh
I have made a basic BAT script to download updates from Avast virus database and then apply them by running the downloaded file.
#ECHO OFF
set downloadFolder=C:\Users\myuser\Downloads\Avast_updates
set downloadUrl=https://install.avcdn.net/vps18/vpsupd.exe
bitsadmin /transfer myAvastUpdates /download /priority normal ^
"%downloadUrl%" "%downloadFolder%\vpsupd.exe"
start /min "Update..." "%downloadFolder%\vpsupd.exe"
exit
Also, I have created a Windows task to run BAT every x hours.
Everything works correctly, but I want to know if there is any way to automatically close the executable window after the update process is finished.
It occurred to me to use TASKILL after x seconds, but that doesn't assure me that the update process finished in x seconds, sometimes it can take longer and sometimes less, plus I don't want to use that command in an program security installer.
Then it occurred to me to send an "Enter" through WshShell.SendKeys:
set SendKeys=CScript //nologo //E:JScript "%~F0"
cls
timeout /t 5 >nul
%SendKeys% "{ENTER}"
#end
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys(WScript.Arguments(0));
But it did not work because that window does not close with "Enter" nor "ALT F4", it closes only if we click on "Done" or on the cross "x" to close the window (if it worked it would have the problem of setting the time again).
Is there a way to automatically close that window once the update process finishes?
vpsupd.exe supports a /silent switch to suppress user interactions.
start /min isn't needed, as it just opens another cmd window, which in turn runs the executable. So just do:
vpsupd.exe /silent
With the help of #Stephan and #Gerhard, the code to download and update Avast was like this:
#ECHO OFF
set "downloadFolder=%userprofile%\Downloads\avast_updates"
set "downloadUrl=https://install.avcdn.net/vps18/vpsupd.exe"
bitsadmin /transfer myAvastUpdates /download /priority normal ^
"%downloadUrl%" "%downloadFolder%\vpsupd.exe"
"%downloadFolder%\vpsupd.exe" /silent
exit
I have searched and searched and this is the closest code I have found:
#echo off
:loop
C:\CryptoCurrency\nexus_cpuminer\start.bat
timeout /t 30 >null
taskkill /f /im nexus_cpuminer.exe >nul
goto loop
A few things: notice the start.bat. The .exe I need to launch has to start via the .bat file because the .bat file contains information the .exe needs.
Secondly, the .exe launches a CMD prompt window which shows me what's going on.
(keep this in mind because this is not your normal .exe, I WANT that CMD prompt window to close when it's KILLED)
I am aware I have it set for 30 seconds. I'm just testing right now. I'd like to set it for 4 hours before the kill command is called. Also, I'd like to set a "delay" of 30 seconds before the whole process starts over. I am running Windows 7 x 64.
You must change the name of the second Batch file to other name (i.e. starter.bat) and execute it via the start internal command in order to execute it in parallel:
#echo off
:loop
start "" cmd /C "C:\CryptoCurrency\nexus_cpuminer\starter.bat"
timeout /t 30 >null
taskkill /f /im nexus_cpuminer.exe >nul
goto loop
The last line in starter.bat file must be the execution of nexus_cpuminer.exe, so when it is killed via taskkill, the .bat file ends immediately.
Another simpler approach is to directly execute nexus_cpuminer.exe in this Batch file, via start "" cmd /C nexus_cpuminer.exe command, so this process be opened in its own cmd.exe window.
If you CALL start.bat, it will return to your 'calling' script.
If you give start.bat a TITLE, you can /FIlter your TASKKILL command to EQ that WINDOWTITLE
How can one open a batch window with some predefined text after the prompt and not invoking the command?
Say I want to invoke notepad.exe with a filename t.txt.
I would create a cmd file with this line:
start notepad "t.txt"
But I want the file to be opened specified by the user.
So the cmd file should just open a cmd window and "type" start notepad without actually executing this.
You can do it using a Vbscript:
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd", 9 'opens cmd.exe
WScript.Sleep 500 'gives cmd a time to load
WshShell.SendKeys "start notepad"
If you want this within your cmd file, try this:
#if (#X)==(#Y) #end /*
start cmd.exe
cscript //E:JScript //nologo "%~f0"
exit/b
*/
var obj = new ActiveXObject("WScript.Shell");
obj.SendKeys("start notepad");
Normally you'd have to launch a command prompt window: start cmd rather than starting notepad directly. But neither start nor cmd offer the function you desire. Would adding a simple echo to your batch file with instructions and a pause prior to actually issuing the command work?
Echo When the other operation completes return to this window
Pause
start notepad "t.txt"
This will provide the echo, then wait for the user to press any key before actually attempting to launch notepad with that filename.
I've recently learned that I can control the size of the CMD window running my program with mode x,y. However I just as recently noticed that this sets the buffer size, and the window will adjust to match or max out at the screen size.
I would like to use mode 100,50 for the window size, but I also want to keep a arger buffer - for development at least I want mode 100,9999.
Is there any way to do this?
I don't think there is a native batch command that gives independent control of buffer and window sizes. .NET can control both, but I don't think VBScript or JScript can access that functionality. But powershell can :-) See How Can I Expand the Width of the Windows PowerShell Console?
Thankfully, the new settings are preserved in the CMD window when PowerShell exits.
It is important that the window size is always less than or equal to the buffer size. To simplify things, I first use MODE to set both the window and buffer to the desired window size, and then I use powershell to set the buffer size.
Here is a simple conSize.bat hybrid batch/powershell script that takes the sizes as parameters:
#echo off
:conSize winWidth winHeight bufWidth bufHeight
mode con: cols=%1 lines=%2
powershell -command "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%3;$B.height=%4;$W.buffersize=$B;}"
To get your desired size, you would simply use
call conSize 100 50 100 9999
There's a 'ConSetBuffer' binary available that does specifically this, and I've found it to work reliably. It and related console utilities are available at the 'conutils.zip' link on this page.
I have written a tiny application for Windows that allows to "maximize" the window and buffer. It could be easily extended to allow passing parameters with custom values.
here another variant:
/*
#echo off & mode 100,50
set "cscfile="
set Pathfile="%WinDir%\Microsoft.NET\Framework\csc.exe"
for /f "delims=" %%a in ('dir /b /a-d /s %PathFile%') do set "cscfile=%%a"
if defined cscfile (
%cscfile% /nologo /out:"%~0.exe" %0
) else exit /b
"%~0.exe"
del "%~0.exe"
cmd /k
*/
using System;
class Program
{
static void Main()
{
Console.SetBufferSize(100, 9999);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Current Logged UserName: " + Environment.UserName);
Console.ResetColor();
Console.WriteLine("[Enter] to continue");
Console.ReadLine();
}
}
The answer to this question didn't work as I got an error regarding variables sent to the PowerShell command, so I modified to work.
The PowerShell command simply adds uiHeightBuffer to the uiHeight variable to show the scroll bar.
Edit: Added the height buffer as the 3rd parameter and TRUE or FALSE as a 4th parameter to enable or disable the scrollbar.
I found this useful when exiting a script with a small message when there's no need for the scrollbar in this case.
Also to enable UTF-8 encoding you have to set the default at the start of the `:CMDSIZE' call and set it at the end, otherwise, the font size goes a bit funny.
Omitting chcp 850 >NUL & and chcp 65001 >NUL & are what you'd do if you didn't want to affect this.
This works in Version: 1909 of Windows 10.
#echo off
title %~nx0
rem Based on this thread here: https://stackoverflow.com/a/13351373
goto MYROUTINE
:CMDSIZE
chcp 850 >NUL & set "uiWidth=%1" & set "uiHeight=%2"
mode %uiWidth%,%uiHeight%
if %4==TRUE (set /a "uiHeightBuffer=uiHeight+%3")
if %4==TRUE (powershell.exe -ExecutionPolicy Bypass -Command "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%uiWidth%;$B.height=%uiHeightBuffer%;$W.buffersize=$B}")
if %4==FALSE (powershell.exe -ExecutionPolicy Bypass -Command "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%uiWidth%;$B.height=%uiHeight%;$W.buffersize=$B}")
chcp 65001 >NUL & goto :EOF
:MYROUTINE
call :CMDSIZE 255 44 222 TRUE
title Do your routine here...
echo Do your routine here...
echo/ & pause
goto :EXITROUTINE
:EXITROUTINE
call :CMDSIZE 40 2 0 FALSE
title Exiting routine message...
echo Exiting routine message...
set /p "=" <NUL
ping localhost -n 3 >NUL & exit
I have found a way to resize the buffer size without influencing the window size. It works thanks to a flaw in how batch works but it gets the job done.
mode 648 78 >nul 2>nul
How does it work? There is a syntax error in this command, it should be "mode 648, 78". Because of how batch works, the buffer size will first be resized to 648 and then the window resize will come but it will never finish, because of the syntax error. Voila, buffer size is adjusted and the window size stays the same. This produces an ugly error so to get rid of it just add the ">nul 2>nul" and you're done.