有没有什么方法可以查看 Windows 7 中距离预定关机还剩多少时间?
我所说的计划关机是指使用命令行shutdown.exe
应用程序计划的关机(或重启),例如:
shutdown /t 600 /s
将会弹出一个消息框,提示距离关机还有 10 分钟,以及关机的实际系统时间。
任何超过600
几秒的时间都会使用气球消息。
我依稀记得 XP 提供了一个带有倒计时功能的 GUI 进度监视器。
它们是如何工作的?剩余关机时间或预定关机时间必须存储在某个地方,我该如何访问它?
我更喜欢通过命令行(即非 GUI)的方法。更重要的是,这可以在 Windows 中实现,即无需任何第三方程序吗?
如果使用标准 Windows 实用程序无法实现这一点(我在这里接近 Stack Overflow 领域),是否有 Windows API(或 .NET,甚至可以在 PowerShell 中使用!)函数?两者都比一些随机的第三方程序更受欢迎。
答案1
这个问题很有趣,所以我写了批处理可以为您完成工作。
基本上它是倒数计时器,我没有在shutdown
其中添加命令,而是把它留作家庭作业。计算不准确,它不关心闰年、月份长度……这主要是为了便于阅读,因为我想让它易于学习。
目前有两个文件一起执行任务,一个启动计时器,另一个在调用时告知从计时器启动以来经过了多少时间。这两个文件可以相当容易地组合成一个 cmd 脚本,这样您就可以使一些行可重复使用(像定义的方法) 也。
好的,让我们看一下脚本,
这是StartTimer.cmd
:
@ECHO OFF
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /A EPOCH=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
ECHO %EPOCH% > Timer.start.state
行首为FOR /F "skip=1 ...
:
1.询问wmic
当前时间和日期。
2.跳过第一行输出,即标题,方法是skip=1
3.读取使用分隔的tokens=1-6
含义的值。%%a-%%f
Spaceor
TAB
4.将值存储到变量中%DateY%
,... %TimeH%
,,%TimeM%
...
之后,在行首SET /A EPOCH=...
我们使用计算的表达式秒数已过1.1.1970
(这是简单的近似值,不是真正的 unix 时间。如果需要精确时间,请查阅 Google。)。
然后在最后一行ECHO %EPOCH% > ...
将计算出的时间写入名为“ Timer.start.state
”的文件中。
和这里GetTimerValue.cmd
:
@ECHO OFF
GOTO CHECKFILE
:TIMEOUT
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /P Timer=<"Timer.start.state"
SET /A EPOCH=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
SET /A Elapsed=%EPOCH%-%Timer%
ECHO "Seconds since timer started: %Elapsed%"
GOTO EOF
:CHECKFILE
IF EXIST "Timer.start.state" (
GOTO TIMEOUT
) ELSE (
ECHO "Timer not started. Start timer by running Timer.cmd"
)
:EOF
这里的代码流不是从上到下的线性流。首先我们GOTO CHECKFILE
进行标记,这样执行命令实际上从 行开始:CHECKFILE
。这里的许多内容与 相同,StartTimer.cmd
因此我仅解释新的或更改的行。
首先我们检查状态文件是否Timer.start.state
存在,如果不存在则终止并显示消息。如果计时器已启动且文件存在则我们继续并进行一些计算:
1.跳转到:TIMEOUT
我们输出已用秒数的位置。您可以为此选择更好的标签...
2. SET /P %Timer% ...
从文件读取开始时间并将值分配给%Timer%
变量。
3. SET /A Elapsed ...
计算开始时间和现在之间的秒数。
4. ECHO "Seconds ...
回显计算值(自计时器启动以来的秒数。
如何获取剩余时间:
您可以%Elapsed%
从中减去%MaxTime%
:
@ECHO OFF
GetTimerValue
SET /A TimeLeft=%MaxTime%-%Elapsed%
ECHO "You have %TimeLeft% seconds remaining"
好的,解释得够多了。以下是完整脚本Timer.cmd
:
此时,忘记了已经说过的一切。这里的批处理文件是独立运行的,因此没有单独的StartTimer.cmd
或GetTimerValue.cmd
,只有这个Timer.cmd
。基本上它仍然相同,但代码流程不同,用法也完全不同。但是,这不会将状态保存到文件,因此您在注销/重启后无法再获取计时器值,如果您需要此使用上述示例将状态保存到文件/从文件读取状态。
不带参数运行时会打印用法/帮助Timer.cmd
。我尚未完全测试过,可能存在一些拼写错误等,参数检查并不万无一失。
@ECHO OFF
GOTO TimerUser%1
:: ===================================
:: Operation is start, (re)start timer
:: ===================================
:TimerUserstart
ECHO %2 | FINDSTR /R "^[1-9]"
IF %ERRORLEVEL%==0 (
SET Timer.max=%2
GOTO TimerStart
) ELSE (
ECHO.
ECHO !! ERROR !!
ECHO You must specify maximum value.
ECHO ===============================
GOTO TimerUser
)
:: =============================================
:: Operation is get, get values if timer running
:: =============================================
:TimerUserget
IF DEFINED Timer.start.state (
GOTO TIMEOUT
) ELSE (
ECHO.
ECHO !! ERROR !!
ECHO Timer is not started, start timer first.
ECHO ========================================
GOTO TimerUser
)
:: ============
:: Usage / Help
:: ============
:TimerUser
ECHO.
ECHO Timer.cmd Usage: Timer.cmd operation [options]
ECHO.
ECHO - Operations
ECHO start Start new timer, n must be specified.
ECHO get Get current value of started timer.
ECHO.
ECHO - Options:
ECHO n Max value in seconds, used to calculate remaining time.
ECHO.
GOTO EOF
:: =============================
:: Update %Timer.epoch% variable
:: =============================
:TimerUpdateEpoch
FOR /F "skip=1 tokens=1-6" %%a IN ('wmic Path Win32_Localtime GET year^,month^,day^,hour^,minute^,second /format:TABLE ^| findstr /r "."') DO (
SET DateD=%%a
SET TimeH=%%b
SET TimeM=%%c
SET DateM=%%d
SET TimeS=%%e
SET DateY=%%f
)
SET /A Timer.epoch=((%DateY%-1970)*365*24*60*60)+(%DateM%*30*24*60*60)+(%DateD%*24*60*60)+(%TimeH%*60*60)+(%TimeM%*60)+%TimeS%
GOTO %Timer.Callback%
:: ===========================================
:: Start new timer destoying/resetting old one
:: ===========================================
:TimerStart
SET Timer.Callback=TimerStartC1
GOTO TimerUpdateEpoch
:TimerStartC1
SET Timer.start.state=%Timer.epoch%
GOTO EOF
:: =============================
:: Echo out current timer values
:: =============================
:TIMEOUT
SET Timer.Callback=TimerEchoJ1
GOTO TimerUpdateEpoch
:TimerEchoJ1
SET /A Timer.elapsed=%Timer.epoch%-%Timer.start.state%
SET /A Timer.remaining=%Timer.max%-%Timer.elapsed%
ECHO "Seconds since timer started: %Timer.elapsed% Time remaining %Timer.remaining%"
GOTO EOF
:EOF
shutdown
与或任何其他命令集成:
文件poweroff.cmd
:
@ECHO OFF
Timer start %1
shutdown -t %1 -s
用途:poweroff <wait_seconds>
启动定时关机并Timer get
获取已用/剩余时间。