0

我正在尝试编写一个简单的批处理文件,它将控制对计算机的访问(使用关机),因此在计算机开启时每 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 语句,但结果是一样的。

4

1 回答 1

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
)

当语句被解析时,any 的当前值%var%被替换,然后语句被执行。在语句执行之前,该值不会被分配给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冒号所在的位置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
)

注意 whenDELAYEDEXPANSION生效时,!var!返回 RUNTIME 值var(即当它改变时),而%var%返回 PARSE-TIME 值var(即在执行之前解析语句时的状态。)

于 2013-04-02T14:16:05.580 回答