2013-04-02 103 views
0

我正在嘗試編寫一個簡單的批處理文件,它將控制對計算機的訪問(使用關機),因此每隔30分鐘計算機啓動時,計算機關閉時至少需要30分鐘。該文件將被放入自動啓動。該算法如下所示:無法在windows批處理文件中的if語句中獲取變量值

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語句,但結果是一樣的。

回答

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 
) 

當語句被解析時,任何%var%的當前值是取代和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在結腸required意味着'去物理結束的文件。

二最簡單的就是這個IF語句之前執行

SETLOCAL ENABLEDELAYEDEXPANSION 

地方(在@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生效,!var!回報RUNTIME的值爲var(即它變化時),而%var%返回的PARSE-TIME值爲var(也就是說,在執行語句之前,語句被解析時)。

+0

謝謝。它解釋了很多。我一定是做了錯誤的goto和標籤 - 我會再試一次。 –

+0

還有一個額外的問題 - 應該是「set/A CLOSETIME =%CURRENTTIME%」。 –

+0

嗯 - 是的。 'SET/a'將算術表達式的值賦給變量,它對空格不敏感。 'SET var = expression'將設置變量'「var」'而不是'「var」'並且前後空格都將包含在分配的STRING值中。因此,使用所使用的結構需要'/ a'。完全正確。 – Magoo

相關問題