Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
803 views
in Technique[技术] by (71.8m points)

batch file - WScript.Shell AppActivate doesn't work every time

I have a few scripts to help running a program in CMD. The first script that starts the sequence is run on startup. In the process, I'm running a VBScript with which I'm trying to focus on the CMD and make it fullscreen. However, sometimes it works and sometimes it doesn't and I'm not changing anything, just restarting the computer over and over again. It doesn't always focus on the cmd window so the problem should be with the AppActivate method.

Here is the code for the first script that runs on startup:

@echo off
TITLE masterBat
START "Master" /B /W myApp.bat
shutdown.exe /s /t 00

Here is the code for myApp.bat:

@echo off
cscript fullscreen.vbs
cd <path>
CMD /C <command>
exit

Here is the code for fullscreen.vbs:

Set ws = WScript.CreateObject("WScript.Shell")
ws.AppActivate "masterBat - myApp.bat"
ws.SendKeys "{F11}"
Set ws = Nothing

The title in the AppActivate call is the title on the cmd when I'm trying to make it fullscreen. I've also tried adding some WScript.Sleep calls in the script but it doesn't seem to help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Wscript.sleep will make it worse. You don't want to sleep.

There are rules. Your program MUST obey one of these rules to be allowed to set the foreground window.

From https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow

The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

?The process is the foreground process.

?The process was started by the foreground process.

?The process received the last input event.

?There is no foreground process.

?The process is being debugged.

?The foreground process is not a Modern Application or the Start Screen.

?The foreground is not locked (see LockSetForegroundWindow).

?The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).

?No menus are active.

An application cannot force a window to the foreground while the user is working with another window. Instead, Windows flashes the taskbar button of the window to notify the user.

What this means is you have two seconds (FOREGROUNDLOCKTIMEOUT) from when your script starts to set another window if your script doesn't have a user interface (as it can't be the foreground window). A message box as the first thing you do will comply (till something else happens). Also Wscript has a message box that times out - WshShell.Popup.

This is to prevent slow starting programs, when the user has got bored and is now working in another program, from then stealing the focus.

Preventive comment Normally people want to argue with me about this. Complain to Microsoft not me. And you can't argue with rules. You can just comply with them.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...