我正在尝试编写一个简单的批处理文件来控制对计算机的访问(使用关机),因此计算机打开时每30分钟一次,计算机关闭时必须至少有30分钟。该文件将被置于自动启动状态。该算法如下所示:
Get from the file time when the computer was last closed (LASTCLOSETIME)
calculate BREAKUNTIL as LASTCLOSETIME + 30 minutes
if CURRENTTIME < BREAKUNTIL {
then shutdown now
} else {
shutdown in 30 minutes
save to the file CURRENTTIME + 30 minutes
}
如果文件不存在,我没有处理第一次运行中发生的情况,但现在不存在问题 - 文件存在且包含有效数据。
我的代码:
::echo off
FOR /F "DELIMS=" %%G IN ('TIME /T') DO SET CURRENTTIME=%%G
echo %CURRENTTIME%
set /A CURRENTTIME = %CURRENTTIME:~0,2%*60 + %CURRENTTIME:~3,2%
echo %CURRENTTIME%
set /P LASTCLOSETIME=<lastclose.txt
set /A BREAKUNTIL = %LASTCLOSETIME% + 30
set /A BREAKUNTIL = %BREAKUNTIL% %% 1440
echo CURRENTTIME: %CURRENTTIME%
echo LASTCLOSETIME: %LASTCLOSETIME%
echo BREAKUNTIL: %BREAKUNTIL%
if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
shutdown -s -t 30
) else (
shutdown -s -t 1800
set CLOSETIME = %CURRENTTIME%
echo CLOSETIME: %CLOSETIME%
set /A CLOSETIME = %CLOSETIME% + 30
set /A CLOSETIME = %CLOSETIME% %% 1440
echo %CLOSETIME%
echo %CLOSETIME% > lastclose.txt
)
PAUSE
问题出在我设置CLOSETIME
的地方。它成功获得CURRENTTIME
的值,我可以看到,例如控制台中的"set CLOSETIME = 886"
但下一行根本不打印此时间,就好像未设置变量一样。它与if语句有关吗?我尝试过使用标签和goto语句,但结果是一样的。
答案 0 :(得分:1)
标准DELAYEDEXPANSION问题。
这是一个复合声明:
if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
shutdown -s -t 30
) else (
shutdown -s -t 1800
set CLOSETIME = %CURRENTTIME%
echo CLOSETIME: %CLOSETIME%
set /A CLOSETIME = %CLOSETIME% + 30
set /A CLOSETIME = %CLOSETIME% %% 1440
echo %CLOSETIME%
echo %CLOSETIME% > lastclose.txt
)
当语句为PARSED时,任何%var%
的CURRENT值将被替换, THEN 将执行该语句。在语句执行之前,该值不会分配给closetime
,因此该语句被解释为
if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
shutdown -s -t 30
) else (
shutdown -s -t 1800
set CLOSETIME = %CURRENTTIME%
echo CLOSETIME:
set /A CLOSETIME = + 30
set /A CLOSETIME = %% 1440
echo
echo > lastclose.txt
)
最简单的治疗方法是将此序列更改为
if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
shutdown -s -t 30
GOTO :EOF
)
shutdown -s -t 1800
set CLOSETIME = %CURRENTTIME%
echo CLOSETIME: %CLOSETIME%
set /A CLOSETIME = %CLOSETIME% + 30
set /A CLOSETIME = %CLOSETIME% %% 1440
echo %CLOSETIME%
echo %CLOSETIME% > lastclose.txt
请注意,冒号为GOTO :EOF
的{{1}}表示“转到物理文件结尾。”
第二个最简单的是执行
required
在此SETLOCAL ENABLEDELAYEDEXPANSION
语句之前的某个地方(通常直接在IF
之后)并将@echo off
更改为
IF
注意到当if "%CURRENTTIME%" LSS "%BREAKUNTIL%" (
shutdown -s -t 30
) else (
shutdown -s -t 1800
set CLOSETIME = %CURRENTTIME%
echo CLOSETIME: !CLOSETIME!
set /A CLOSETIME = !CLOSETIME! + 30
set /A CLOSETIME = !CLOSETIME! %% 1440
echo !CLOSETIME!
echo !CLOSETIME! > lastclose.txt
)
生效时,DELAYEDEXPANSION
返回RUNTIME值!var!
(即更改时),而var
返回PARSE-TIME值{ {1}}(即在执行之前解析语句时的情况。)