2

when I have

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

this results in the wanted variable being set, if a corresponding file was found. But when I change the last line to

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

it says "\IrfanView\i_view32.exe" can't be processed syntactically at this point, which obviously refers to the set command. (echo works as gives the correct result). SET has a problem with the parenthesis it seems, but when I thought I could fix this by using quotes

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

I noticed that it doesn't fix it. What did I miss/how can I achieve this? (I read about delayedexpansion for normal variables but is that applicable for loop variables like %%a? if so: how?)


The following is the code as a whole:

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
commander_keen
  • 691
  • 1
  • 6
  • 11
  • 1
    `FOR /F "tokens=*" %%a IN ('dir /b /s "%PROGRAMFILES^(X86^)%\%IrfanFile32%"') DO SET "IrfanPath=%%a"` – npocmaka Mar 05 '16 at 21:25
  • Your code above looks like you're looking for the file `"C:\Program Files (x86)\i_view32.exe"`. Your error suggests that at some point you're referencing `"\IrfanView\i_view32.exe"`. That error isn't coming from the code you posted here. – Wes Larson Mar 06 '16 at 05:11
  • @npocmaka: I tried that. But that makes it search like "everywhere" on the drive for minutes. – commander_keen Mar 06 '16 at 12:40
  • @WesLarson I look for the file in *all subdirectories* of "C:\Program Files (x86)\" and hand back the directory where the file was found. The result is correct when using echo. (e.g. stating "C:\Program Files(x86)\IrfanView\i_view32.exe") – commander_keen Mar 06 '16 at 12:41
  • Don't use `{}` in `if` clauses, use `""` instead: `if /I "!PathKorrekt!"=="j"` (this way you won't run into trouble with white-spaces or special characters) – aschipfl Mar 06 '16 at 13:39

1 Answers1

3

There must be more to your code that you are not showing, because the code you posted cannot give the error you are describing for many reasons:

  • The SET command does not care about parentheses
  • Expansion of FOR variables like %%a protects against poison characters like parenthesis
  • Adding quotes to your SET statement would protect against poison character literals (which you don't have anyway)

The error must be elsewhere in your code. My guess is you have a parenthesized IF or FOR block that includes an unquoted %IrfanPath%, which would prematurely close your parenthesized block because of the ) in Program Files (x86).

You could probably find the problem quickly if you disable ECHO OFF in your script (keep ECHO ON).

Update in response to edited question:

The problem is exactly as I predicted - within a parenthesized IF statement later in your code:

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

Your %IrfanPath% contains ), and it is not quoted. So after expansion, it logically becomes:

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

And there you have the source of your error message.

The simplest solution is to put quotes around the expanded path:

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

I believe your code will then work properly. However, you are using GOTO to branch to a :label within your parenthesized IF block, which is a big no-no because it will break the IF block. You also have an unbalanced closing paren that is effectively functioning as a comment:

) else GOTO Main

See (Windows batch) Goto within if block behaves very strangely for more info.

I think your code is a special case where it happens to work OK. But more often then not it leads to crazy results that are difficult to debug if you do not understand the mechanism.

I would restructure your code as follows:

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

Note that delayed expansion is no longer required with this structure.

Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • When I disable ECHO OFF it shows exactly what I'm expecting: `"D:\test mit leer>FOR /F "tokens=*" %a IN ('dir /b /s "C:\Program Files (x86)\i_v iew32.exe"') DO SET IrfanPath=%a D:\test mit leer>SET IrfanPath=C:\Program Files (x86)\IrfanView\i_view32.exe` stating `"\IrfanView\i_view32.exe" kann syntaktisch an dieser Stelle nicht verarbeitet werden."` (can't be processed syntactically at this point) No matter if with or without quotes, but as you said that doesn't matter anyway... I will show more code in the OP in a minute, maybe that helps, thank you – commander_keen Mar 06 '16 at 12:27
  • @commander_keen - But that error message must not have occurred immediately after the FOR statement. It must have occurred later on after (within) the big IF DEFINED block. I will update my answer to explain – dbenham Mar 06 '16 at 14:03
  • Doh! I was too early. Okay, lession learned, thank you very much. – commander_keen Mar 06 '16 at 22:03