0
:start
CLS
echo.
echo ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
del "\\%%A\C$\Windows\Downloaded Program Files\Olympus.exe" /F /S /Q >nul 2>&1
echo %%A
pause
if exist "\\%%A\C$\Program Files\Common Files\Olympus Shared" call :skip
if not exist "\\%%A\C$\Program Files\Common Files\Olympus Shared" call :fix
if not exist "\\%%A\C$\Program Files (x86)\Common Files\Olympus Shared" call :fix
:fix
echo fix needed on %%A
pause
esentutl /y "Olympus.exe" /d "\\%%A\C$\Windows\Downloaded Program Files\Olympus.exe"
"%~dp0psexec.exe" \\%%A -accepteula "\\%%A\C$\Windows\Downloaded Program Files\Olympus.exe"

:skip
echo not needed on %%A
pause
)

Getting confused with this and need some help. It's been a long day, I'm sure it's easy but I cant see it. Echo %%A (3rd Line) will echo the computer name from the list of pc's in the text file I am running a driver install patch on. The minute it hits the if exist, if not exist section the %%A variable is then broken and just reports %A causing the rest of the stuff to fail.

I was trying the usual goto options but soon found out they break for loops. I was happy to find that using call routines allowed the for loop to keep going but now I'm left with a broken variable.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Tika9o9
  • 405
  • 4
  • 22
  • [**Never** use `:label` nor `:: label-like comment` inside a command block enclosed in `()` parentheses](http://stackoverflow.com/a/32147995/3439404) – JosefZ Dec 13 '16 at 21:31
  • `call :fix %%A` and in `:Fix` it becomes `%1`. `esentutl` is a database repair utility. –  Dec 13 '16 at 21:40

2 Answers2

1

Next code snippet shows call a subroutine logic (however I can't attest correctness of esentutl and psexec use):

for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
  del "\\%%A\C$\Windows\Downloaded Program Files\Olympus.exe" /F /S /Q >nul 2>&1
  echo %%A
  pause
  if exist "\\%%A\C$\Program Files\Common Files\Olympus Shared\" (
    call :skip %%A
  ) else ( 
    call :fix %%A
  )
  if not exist "\\%%A\C$\Program Files (x86)\Common Files\Olympus Shared\" call :fix %%A
)
rem skip procedures
goto :SomethingNext

:fix
echo fix needed on %1
pause
esentutl /y "Olympus.exe" /d "\\%1\C$\Windows\Downloaded Program Files\Olympus.exe"
"%~dp0psexec.exe" \\%1 -accepteula "\\%1\C$\Windows\Downloaded Program Files\Olympus.exe"
rem return from a subroutine
exit /B

:skip
echo not needed on %1
pause
rem return from a subroutine
exit /B

:SomethingNext

To establish 64 or 32 bit program files structure (but not both simultaneously):

for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
  del "\\%%A\C$\Windows\Downloaded Program Files\Olympus.exe" /F /S /Q >nul 2>&1
  echo %%A
  pause

  rem suppose that no folder exists and (therefore) fix is necessary
  set "pf32="
  set "pf86="
  set "needFix=yes"

  rem deny the premise if either folder exists
  if exist "\\%%A\C$\Program Files\Common Files\Olympus Shared\" (
    set "needFix="
    set "pf32=pf32"
  )
  if exist "\\%%A\C$\Program Files (x86)\Common Files\Olympus Shared\" (
    set "needFix="
    set "pf86=pf86"
  )

  rem resume the premise if both folders exist
  if defined pf32 if defined pf64 set "needFix=yes" 

  if defined needFix ( call :fix %%A ) else ( call :skip %%A )
)
rem skip procedures
goto :SomethingNext
JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • I tried that but seems to always install the patch even though the folder exists on target PC...Thanks for the answer! I'm probably missing something... – Tika9o9 Dec 13 '16 at 22:12
  • I know why, need to establish 64 or 32 bit program files structure, they are both not going to exist and also exist – Tika9o9 Dec 13 '16 at 22:20
  • `If defined ProgramFiles(x86) (echo On 64 bit) else (echo 32 bit)` –  Dec 13 '16 at 23:15
  • @Noodles Nope. We can't test variable existence at remote computers in such way. – JosefZ Dec 13 '16 at 23:27
  • Then test the folder `if exist "\\server\C$\Program Files (x86)" etc` –  Dec 13 '16 at 23:54
1
for /f "usebackq tokens=*" %%A in ("%~dp0pxhosts.txt") do (
del "\\%%A\C$\Windows\Downloaded Program Files\Olympus.exe" /F /S /Q >nul 2>&1
echo %%A
pause
if exist "\\%%A\C$\Program Files\Common Files\Olympus Shared" call :skip "%%A"
if not exist "\\%%A\C$\Program Files\Common Files\Olympus Shared" call :fix "%%A"
if not exist "\\%%A\C$\Program Files (x86)\Common Files\Olympus Shared" call :fix "%%A"
)
goto :eof

:fix
echo fix needed on %~1
pause
esentutl /y "Olympus.exe" /d "\\%~1\C$\Windows\Downloaded Program Files\Olympus.exe"
"%~dp0psexec.exe" \\%%A -accepteula "\\%~1\C$\Windows\Downloaded Program Files\Olympus.exe"

goto :eof

:skip
echo not needed on %~1
pause

goto :eof

Batch simply executes commands until it reaches a goto, exit or end-of-file. It has no concept of "procedures" or "functions" and :name is simply a label - and labels are not allowed within a block statement.

Nominally, the metavariable %%A is not visible with a subroutine (in fact, this appears to work) so %%A is passed to each of the subroutines as a quoted parameter. Within the subroutines, %~1 retrieves and dequotes the first parameter, accessing the metavariable.

Note that goto :eof is used to skip over the remaining physical code in the batch file. This is understood by batch to mean "go to the end of file" - the label :eof is a required part of the syntax, but should not be entered as a label in the code.

I'd suggest you examine your logic however. The if exist will skip, but the if not exist will fix, so the fix is applied wherever "...Olympus Shared" is missing and skipped if it exists.

Magoo
  • 77,302
  • 8
  • 62
  • 84