2016-03-05 94 views
1

當我有如何在set命令中使用括號來轉義變量?

SET IrfanFile32=i_view32.exe  
FOR /F "tokens=*" %%a IN ('dir /b /s "%ProgramFiles%\%IrfanFile32%" 2^>NUL') DO SET IrfanPath=%%a 

這導致想變量被設置,如果相應的文件被發現。但是,當我最後一行改爲

FOR /F "tokens=*" %%a IN ('dir /b /s "%PROGRAMFILES(X86)%\%IrfanFile32%"') DO SET IrfanPath=%%a 

它說:「\ IrfanView中\ i_view32.exe」不能語法在這一點上,這顯然指的是一組指令處理。 (回聲的作用是給出正確的結果)。 SET有似乎括號中的問題,但是當我想我可以用引號

FOR /F "tokens=*" %%a IN ('dir /b /s "%PROGRAMFILES(X86)%\%IrfanFile32%"') DO SET "IrfanPath=%%a" 

我注意到,它並沒有解決它解決這個問題。 我錯過了什麼/我該如何實現? (我讀delayedexpansion正常的變數,但是是適用於像%%的循環變量,如果是的話:怎麼了?)


以下是代碼作爲一個整體:

REM @echo off 
SETLOCAL ENABLEDELAYEDEXPANSION 
SET IrfanFile32=i_view32.exe 
SET IrfanFile64=i_view64.exe 
SET IrfanParams="" 
SET SourcePath=%~1\nul 
:Start 
FOR /F "tokens=3,4,5,6,7,8,9" %%a IN ('REG QUERY HKCU\Environment /v IrfanPath ^|find "IrfanPath"') DO (
    REM echo %IrfanPath% 
    SET IrfanPath=%%a %%b %%c %%d %%e %%f %%g 
) 
echo. 
IF NOT DEFINED IrfanPath (GOTO Init) ELSE (GOTO Main) 
:Init 
    echo Dies scheint mein erster Start auf diesem System zu sein. 
    echo Ich benötige IrfanView (inkl. JPG_TRANSFORM Plugin) um zu funktionieren 
    echo und suche nun im Ordner %ProgramFiles% und allen Unterverzeichnissen 
    echo nach IrfanViews Startdatei namens %IrfanFile32% bzw. %IrfanFile64%. 
    echo. 
    IF EXIST "%PROGRAMFILES(X86)%" echo 64bit Betriebssystem gefunden, suche zusätzlich in %PROGRAMFILES(X86)%. 
    echo. 
    FOR /F "tokens=*" %%a IN ('dir /b /s "%ProgramFiles%\%IrfanFile32%" 2^>NUL') DO SET IrfanPath=%%a 
    FOR /F "tokens=*" %%a IN ('dir /b /s "%ProgramFiles%\%IrfanFile64%" 2^>NUL') DO SET IrfanPath=%%a 
    FOR /F "tokens=*" %%a IN ('dir /b /s "%PROGRAMFILES(X86)%\%IrfanFile32%"') DO SET IrfanPath=%%a 
    IF DEFINED IrfanPath (
    echo Ich habe IrfanView hier gefunden: %IrfanPath% 
    :Entscheidung 
    SET /P PathKorrekt=Ist das der gewünschte Pfad? [^(J^)a/^(N^)ein] 
    if /i {!PathKorrekt!}=={j} (goto :yes) 
    if /i {!PathKorrekt!}=={ja} (goto :yes) 
    if /i {!PathKorrekt!}=={n} (goto :no) 
    if /i {!PathKorrekt!}=={nein} (goto :no) 
    echo Das war keine gültige Antwort. Benutze ja, nein, j oder n. 
    GOTO Entscheidung 

    :yes 
    REG ADD HKCU\Environment /v IrfanPath /d "%IrfanPath%" >nul 
    GOTO Start 
) 
    :no 
    SET /P IrfanPath=Bitte gib den Pfad zur %IrfanFile32% bzw. %IrfanFile64% an: 
    IF NOT EXIST "%IrfanPath%\%IrfanFile32%" (
    IF NOT EXIST "%IrfanPath%\%IrfanFile64%" (
     echo Keine %IrfanFile32% oder %IrfanFile64% in diesem Ordner gefunden, nochmal bitte. 
    GOTO no 
    ) 
) ELSE (
    IF EXIST "%IrfanPath%\%IrfanFile32%" (
     REG ADD HKCU\Environment /v IrfanPath /d "%IrfanPath%\%IrfanFile32%" 
    ) 
    IF EXIST "%IrfanPath%\%IrfanFile64%" (
     REG ADD HKCU\Environment /v IrfanPath /d "%IrfanPath%\%IrfanFile64%" 
    ) 
    PAUSE > NUL 
    GOTO Start 
) 
) else GOTO Main 

:Main 
REM more code here 
+1

'FOR/F「tokens = *」%% a IN('dir/b/s「%PROGRAMFILES ^(X86 ^)%\%IrfanFile32%」')DO SET「IrfanPath = %% a」' – npocmaka

+0

上面的代碼看起來像是在查找文件「C:\ Program Files(x86)\ i_view32.exe」。你的錯誤表明在某些時候你正在引用'「\ IrfanView \ i_view32.exe」'。該錯誤不是來自您在此發佈的代碼。 –

+0

@npocmaka:我試過了。但是,這使得它在搜索驅動器上的「無處不在」幾分鐘。 –

回答

3

有一定要多去你的代碼,你無法顯示,因爲你發佈的代碼不能給你所描述的原因是多方面的錯誤:

  • SET命令不關心括號
  • 擴展的像%%a變量防止毒的人物,如括號
  • 加上引號,以您的SET語句將防止毒字符文字(你沒有反正)

誤差必須在別處你的代碼。我的猜測是你有一個加括號的IF或FOR塊,其中包含一個不加引號的%IrfanPath%,由於Program Files (x86)中的)會過早地關閉括號中的塊。

如果在腳本中禁用ECHO OFF(保持ECHO ON),您可能會很快發現問題。

IF DEFINED IrfanPath (
    echo Ich habe IrfanView hier gefunden: %IrfanPath% 
    ... additional code ... 
) 

%IrfanPath%包含),它是: - 內帶括號的IF語句後面的代碼

的問題是完全按照我的預測:

響應編輯的問題更新沒有引用。所以在擴展之後,它在邏輯上變成:

IF DEFINED IrfanPath (
    echo Ich habe IrfanView hier gefunden: C:\Program Files (x86 
) 
    \IrfanView\i_view32.exe 
    ... additional code ... 
) 

並且在那裏你有錯誤信息的來源。

最簡單的辦法是把周圍的擴展路徑報價:

IF DEFINED IrfanPath (
    echo Ich habe IrfanView hier gefunden: "%IrfanPath%" 
    ... additional code ... 
) 

我相信,那麼你的代碼將正常工作。但是,您正在使用GOTO分支到帶括號的IF塊中的:標籤,這是一個很大的禁忌,因爲它會中斷IF塊。你也有被有效地充當評論不平衡收盤括號:

) else GOTO Main 

更多信息,請參見(Windows batch) Goto within if block behaves very strangely

我認爲你的代碼是一個特殊的情況,它恰好工作正常。但更常見的是,如果您不瞭解機制,則會導致難以調試的瘋狂結果。

如下我會調整你的代碼:

REM @echo off 
setlocal DisableDelayedExpansion 
SET IrfanFile32=i_view32.exe 
SET IrfanFile64=i_view64.exe 
SET IrfanParams="" 
SET "SourcePath=%~1\nul" 
:Start 
FOR /F "tokens=3,4,5,6,7,8,9" %%a IN ('REG QUERY HKCU\Environment /v IrfanPath ^|find "IrfanPath"') DO (
    REM echo %IrfanPath% 
    SET IrfanPath=%%a %%b %%c %%d %%e %%f %%g 
) 
echo. 
IF NOT DEFINED IrfanPath (GOTO Init) ELSE (GOTO Main) 
:Init 
    echo Dies scheint mein erster Start auf diesem System zu sein. 
    echo Ich benötige IrfanView (inkl. JPG_TRANSFORM Plugin) um zu funktionieren 
    echo und suche nun im Ordner %ProgramFiles% und allen Unterverzeichnissen 
    echo nach IrfanViews Startdatei namens %IrfanFile32% bzw. %IrfanFile64%. 
    echo. 
    IF EXIST "%PROGRAMFILES(X86)%" echo 64bit Betriebssystem gefunden, suche zusätzlich in %PROGRAMFILES(X86)%. 
    echo. 
    FOR /F "tokens=*" %%a IN ('dir /b /s "%ProgramFiles%\%IrfanFile32%" 2^>NUL') DO SET IrfanPath=%%a 
    FOR /F "tokens=*" %%a IN ('dir /b /s "%ProgramFiles%\%IrfanFile64%" 2^>NUL') DO SET IrfanPath=%%a 
    FOR /F "tokens=*" %%a IN ('dir /b /s "%PROGRAMFILES(X86)%\%IrfanFile32%"') DO SET IrfanPath=%%a 

    if not defined IrfanPath goto :no 

    echo Ich habe IrfanView hier gefunden: %IrfanPath% 
:Entscheidung 
    SET /P PathKorrekt=Ist das der gewünschte Pfad? [^(J^)a/^(N^)ein] 
    if /i "%PathKorrekt%"=="j" (goto :yes) 
    if /i "%PathKorrekt%"=="ja" (goto :yes) 
    if /i "%PathKorrekt%"=="n" (goto :no) 
    if /i "%PathKorrekt%"=="nein" (goto :no) 
    echo Das war keine gültige Antwort. Benutze ja, nein, j oder n. 
    GOTO Entscheidung 

:yes 
    REG ADD HKCU\Environment /v IrfanPath /d "%IrfanPath%" >nul 
    GOTO Start 

:no 
    SET /P IrfanPath=Bitte gib den Pfad zur %IrfanFile32% bzw. %IrfanFile64% an: 
    IF NOT EXIST "%IrfanPath%\%IrfanFile32%" (
    IF NOT EXIST "%IrfanPath%\%IrfanFile64%" (
     echo Keine %IrfanFile32% oder %IrfanFile64% in diesem Ordner gefunden, nochmal bitte. 
     GOTO no 
    ) 
) ELSE (
    IF EXIST "%IrfanPath%\%IrfanFile32%" (
     REG ADD HKCU\Environment /v IrfanPath /d "%IrfanPath%\%IrfanFile32%" 
    ) 
    IF EXIST "%IrfanPath%\%IrfanFile64%" (
     REG ADD HKCU\Environment /v IrfanPath /d "%IrfanPath%\%IrfanFile64%" 
    ) 
    PAUSE > NUL 
    GOTO Start 
) 

:Main 
REM more code here 

注意,延遲擴展不再與這種結構要求。

+0

當我禁用ECHO OFF時,它顯示了我期待的內容:''D:\ test mit leer> FOR/F「tokens = *」%a IN('dir/b/s「C:\ Program Files(x86)\ i_view32.exe'')DO SET IrfanPath =%a D:\ test mit leer> SET IrfanPath = C:\ Program Files文件(x86)\ IrfanView \ i_view32.exe'說明'「\ IrfanView \ i_view32.exe」可以用來模擬Stelle nicht verarbeitet werden。「(不能在此處進行句法處理)無論如果有或沒有引號,但正如你所說,無論如何不重要...我會在一分鐘內在OP中顯示更多的代碼,也許這有幫助,謝謝 –

+0

@commander_keen - 但是那個錯誤信息一定不會發生在FOR聲明。它必須在大IF定義塊之後(之內)發生。我會更新我的答案來解釋 – dbenham

+0

Doh!我爲時尚早。好吧,學會了解,非常感謝你。 –