2016-03-05 96 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!我为时尚早。好吧,学会了解,非常感谢你。 –