Page 1 of 1

The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 05:06
by lmstearn
The aim here is to locate a directory MYDIRFOUND in a set of folders FOLDERSET over a range of drives.

Code: Select all

Setlocal EnableDelayedExpansion
SET "FOLDERSET=ZZ* D* S* T*"

for %%T in (B) do (
if exist %%T: (

%%T:
REM cd ..\.. corrected to
cd \
for /D %%C in (!FOLDERSET!) do (
pushd %%C
REM CANNOT cd here or screws up the loop just above. pushd and popd are better.

for /D /R %%K in (*) do (
REM MUST be (*) or will recurse for subfolders matching FOLDERSET. MYDIRFOUND is not one of them.

echo %%K
pause

Set "MYTEMP=%%K"
SET "_MYDIR=!MYTEMP:MYDIRFOUND=!"

IF NOT !MYTEMP!==!_MYDIR! (
call SET "_MYDIR=%%~K"
echo !_MYDIR!
pause
goto MYDIRFOUND
)
)
popd
)

REM DRIVE LOOP AND EXIST
)
)
goto eof
:MYDIRFOUND
echo success
pause


Unfortunately the inner K loop with (*) ignores the previous C loop over FOLDERSET and searches all folders on the drive. Somewhat overkill.
I've tried the above using dir, but ran into similar contortions. Any suggestions?

Re: The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 05:17
by foxidrive
This cd will put you in a folder that depends on what the current folder was on the drive to begin with.

Code: Select all

cd ..\..


Another option is to give some examples of folders to be found on the drives, and someone can write a script to do it.

Re: The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 06:03
by lmstearn
foxidrive wrote:Another option is to give some examples of folders to be found on the drives, and someone can write a script to do it.


What's wrong with MYDIRFOUND?
An other option is to hope the code fairy pops in overnight and leaves a nice little recursive surprise under my elusive little XMAS Folder_Tree.
Perhaps the best answer is in recursion, failing that, something else? Would PowerShell work better?

Wait... suppose I get the leftmost folder of %%K and compare that to %%C. Problem solved? Better to pushd and popd outside the K loop.

Re: The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 06:16
by foxidrive
lmstearn wrote:
foxidrive wrote:Another option is to give some examples of folders to be found on the drives, and someone can write a script to do it.


What's wrong with MYDIRFOUND?
An other option is to hope the code fairy pops in overnight and leaves a nice little recursive surprise under my elusive little XMAS Folder_Tree.
Perhaps the best answer is in recursion, failing that, something else? Would PowerShell work better?


See here: viewtopic.php?f=3&t=6108

Re: The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 06:24
by lmstearn
Thanks Foxidrive, I read that and thought about it. I can post the whole file here if you like, but believe me, a lot more works needs to be done especially commenting. In the meantime, you guys just being here makes my brain tick over just that little bit more. :)

Re: The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 07:26
by foxidrive
lmstearn wrote:post the whole file here if you like


So this is a segment from your batch file?

Describe the task that needs to be performed and you may get a module to drop in.

Re: The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 07:43
by Squashman
Helps to format your code. Makes it a lot easier to follow when you have nested FOR and IF commands.

Code: Select all

Setlocal EnableDelayedExpansion
SET "FOLDERSET=ZZ* D* S* T*"

for %%T in (B) do (
   if exist %%T: (

      %%T:
      REM cd ..\.. corrected to
      cd \
      for /D %%C in (!FOLDERSET!) do (
         REM CANNOT cd here or screws up the loop just above. pushd and popd are better.
         pushd %%C

         REM MUST be (*) or will recurse for subfolders matching FOLDERSET. MYDIRFOUND is not one of them.
         for /D /R %%K in (*) do (

            echo %%K
            pause

            Set "MYTEMP=%%K"
            SET "_MYDIR=!MYTEMP:MYDIRFOUND=!"

            IF NOT !MYTEMP!==!_MYDIR! (
               call SET "_MYDIR=%%~K"
               echo !_MYDIR!
               pause
               goto MYDIRFOUND
            )
         )
         popd
      )

   REM DRIVE LOOP AND EXIST
   )
)
goto eof
:MYDIRFOUND
echo success
pause

Re: The contorted Logic of Dir & For/D

Posted: 08 Dec 2014 21:32
by lmstearn
Squashman wrote:Helps to format your code. Makes it a lot easier to follow when you have nested FOR and IF commands.


Yes, having tried that originally but ran into problems with tabs. But your format with spaces is superior. Just have to configure Notepad++ not to indent with tabs. :)

Re: The contorted Logic of Dir & For/D

Posted: 09 Dec 2014 08:23
by Squashman
lmstearn wrote:
Squashman wrote:Helps to format your code. Makes it a lot easier to follow when you have nested FOR and IF commands.


Yes, having tried that originally but ran into problems with tabs. But your format with spaces is superior. Just have to configure Notepad++ not to indent with tabs. :)

Has nothing to do with TABS. I did use TABS and I do use N++. The forum software converts the TABS to spaces, when you paste code into the forum. I indent with tabs all day, all night, 24 hours a day, 7 days a week, 365 days a year!

Re: The contorted Logic of Dir & For/D

Posted: 11 Dec 2014 23:49
by lmstearn
Squashman wrote:Has nothing to do with TABS. I did use TABS and I do use N++. The forum software converts the TABS to spaces, when you paste code into the forum. I indent with tabs all day, all night, 24 hours a day, 7 days a week, 365 days a year!

I figured something like that was the case. The problem was something to do with tabs inside an if...else block but can't reproduce now. I wonder if VS can format batch.
Here's the alpha code to be uploaded.
It's tested, but not for all combos.
Major problem is that the UAC stuff at the beginning doesn't like being run out of a 7z archive.

Code: Select all

:::::::::::::::::::::::::::::::::::::::::
:: Automatically check & get admin rights (thanks to TanisDLJ at Stackoverflow)
:::::::::::::::::::::::::::::::::::::::::
@echo off
color 1E
mode 100,50
VERIFY > nul
CLS
:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\icacls.exe" "%SYSTEMROOT%\system32\config\system"

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    echo args = "" >> "%temp%\getadmin.vbs"
    echo For Each strArg in WScript.Arguments >> "%temp%\getadmin.vbs"
    echo args = args ^& strArg ^& " "  >> "%temp%\getadmin.vbs"
    echo Next >> "%temp%\getadmin.vbs"
    echo UAC.ShellExecute "%~s0", args, "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs" %*
    exit /B

:gotAdmin
    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )

Setlocal EnableDelayedExpansion & CD /D "%~dp0"
::::::::::::::::::::::::::::
::START
::::::::::::::::::::::::::::



REM Run shell as admin (example) - put here code as you like



set CREATKIT=
set TESVGAME=
set TES5EDIT=


tasklist /fi "IMAGENAME eq CreationKit.exe" | find /i "CreationKit.exe" > nul

if %errorlevel% EQU 0 set CREATKIT=Creation Kit is running


tasklist /fi "IMAGENAME eq tesv.exe" | find /i "tesv.exe" > nul

if %errorlevel% EQU 0 set TESVGAME=Skyrim is running


tasklist /fi "IMAGENAME eq TES5Edit.exe" | find /i "TES5Edit.exe" > nul

if %errorlevel% EQU 0 set TES5EDIT=TES5Edit is running

echo(
echo(
If DEFINED CREATKIT echo %CREATKIT%
If DEFINED TESVGAME echo %TESVGAME%
If DEFINED TES5EDIT echo %TES5EDIT%
echo(
echo(



echo                     Welcome to the FNIS Remnant Removal Tool!
echo(
echo        Before continuing this script, check the install status of the FNIS Creature Pack:
echo(
echo    If installed, open the FNIS Generator and click "De-Install Creatures", and quit the Generator.
echo(
echo   Then deactivate and uninstall FNIS, FNIS Creature Pack, and FNIS Spells through your mod manager.
echo(
:PROMPTBEGIN
SET "validateText="
SET /P validateText="________________________________Are you ready? type Y or N_________________________________Y/N]"
echo(
echo(
@echo off

if /I !validateText!==y goto BEGIN
if /I !validateText!==n goto ENDSCRIPT
GOTO PROMPTBEGIN

:BEGIN


tasklist /fi "IMAGENAME eq GenerateFNISforUsers.exe" | find /i "GenerateFNISforUsers.exe" > nul

if %errorlevel% EQU 1 goto REMOVEPROMPT

:PromptTerminate
REM Eliminate poison chars on <CR>
SET "FNISRUNNING="
echo(
SET /P FNISRUNNING="FNIS Generator is still running! Type T to terminate it or K to keep it running and cancel out.[T/K]"
@echo off
if /I !FNISRUNNING!==t goto NOFNISRUN
if /I !FNISRUNNING!==k goto ENDSCRIPT
goto PromptTerminate

:NOFNISRUN
@echo off
taskkill /im GenerateFNISforUsers.exe /f


:REMOVEPROMPT
color 1E


SET "validateText="
echo(
SET /P validateText="___________All FNIS generated remnants to be removed at this time? (no recycle bin)__________(Y/N)"

if /I !validateText!==n goto ENDSCRIPT
if /I !validateText!==y goto BEGINDELETE
goto REMOVEPROMPT


:BEGINDELETE
@echo off
echo(
echo _______________________________......Processing for %USERNAME%......__________________________________
echo(
set /A FNISDRIVE=0
REM SET "FOLDERSET=Users\New\Desktop*"
SET "FOLDERSET=F* G* R* S*"
set CURRDRIVE=B
SET SKYRIMFOLDER=

:SEARCHDRIVES


REM BLOCK

for %%B in (B C D E F G) do (
if exist %%B: (
%%B:
cd \
if NOT DEFINED SKYRIMFOLDER (
for /D %%C in (!FOLDERSET!) do (
pushd %%C
for /D /R %%G in ("*") do (
if exist "%%G\tesv.exe" (
call set "SKYRIMFOLDER=%%G"
GOTO GOTSKYRIMFOLDER
)
)
popd
)
) else (

if %CURRDRIVE%==%%B (
for /D %%C in (!FOLDERSET!) do (
pushd %%C
for /D /R %%G in ("*") do (

@echo off
if exist "%%G\tesv.exe" (
call set "SKYRIMFOLDER=%%G"
echo(
echo | set /p validateText="Skyrim files are detected on another drive."
:DRIVEPROMPT
set "validateText="
echo(
set /p "validateText=Type Y to delete FNIS remnant files there or N to quit. (Y/N)"
echo(
@echo off
if /I !validateText!==n goto FINISH
if /I !validateText!==y GOTO GOTSKYRIMFOLDER
goto DRIVEPROMPT

)
)
popd
)
)

)
REM SKYRIMFOLDER DEFINED
)
REM Exist Drive
)
REM Drives Loop
REM BLOCK


if DEFINED SKYRIMFOLDER (
IF %FNISDRIVE% EQU 0 (
GOTO ENDSCRIPT
) else (
GOTO FINISH
)
)

echo(
echo No Skyrim installed on any of the "standard" paths.
:NOSKYRIMPROMPT
SET "validateText="
echo(
SET /P validateText="Input at least the first letter of its root install path (no wildcards) or space to exit."
set FOLDERSET=%validateText:~0,1%
FOR %%G IN (a b c d e f g h i j k l m n o p q r s t u v x y z 0 1 2 3 4 5 6 7 8 9) DO (
If !FOLDERSET!==%%G (
set "FOLDERSET=!validateText!*"
set CURRDRIVE=B
SET SKYRIMFOLDER=
GOTO SEARCHDRIVES
)
)
if "!FOLDERSET!"==" " GOTO ENDSCRIPT
goto NOSKYRIMPROMPT




:GOTSKYRIMFOLDER
REM Only one occurrence of TES5.exe considered on each drive

for %%T in (%CURRDRIVE%) do (
if exist %%T: (
%%T:
cd \

for /D %%C in (!FOLDERSET!) do (
pushd %%C

for /D /R %%K in ("*") do (
Set FNISTEMP=%%K
SET _FNISFOLDERUSERS=!FNISTEMP:GenerateFNIS_for_Users=!

IF NOT !FNISTEMP!==!_FNISFOLDERUSERS! (
call SET "_FNISFOLDERUSERS=%%K"
goto FNISFOLDERUSERSFOUND
)
)
popd
)
)
)

for %%T in (%CURRDRIVE%) do (
if exist %%T: (
%%T:
cd \

for /D %%C in (!FOLDERSET!) do (
pushd %%C

for /D /R %%K in ("*") do (
Set FNISTEMP=%%K
SET _FNISFOLDERMODS=!FNISTEMP:GenerateFNIS_for_Mods=!

IF NOT !FNISTEMP!==!_FNISFOLDERMODS! (
call SET "_FNISFOLDERMODS=%%K"
goto FNISFOLDERMODSFOUND
)
)
popd
)
)
)





:PATHPROMPT
SET "validateText="

set /p "=%CURRDRIVE%" <nul
SET /P validateText=": is where Skyrim exists but FNIS isn't found on standard or input paths. Search more drives? (Y/N)"
if /I !validateText!==Y GOTO INCREMENTDRIVE
if /I !validateText!==n GOTO ENDSCRIPT
goto PATHPROMPT
REM Do the data directories match?


:FNISFOLDERUSERSFOUND

set "FNISTEMP=\temporary_logs"
REM just in case the temporary_logs folder is found
SET FNISFOLDERUSERS=!_FNISFOLDERUSERS:FNISTEMP=\!

IF !FNISFOLDERUSERS!==!_FNISFOLDERUSERS! (
SET FNISTEMP=!_FNISFOLDERUSERS!
) else (
SET FNISTEMP=!FNISFOLDERUSERS!
)

set FNISFOLDER=!FNISTEMP:\tools\GenerateFNIS_for_Users=\!
GOTO FNISCOMPARE

:FNISFOLDERMODSFOUND

set FNISTEMP=\temporary_logs
REM just in case the temporary_logs folder is found
SET FNISFOLDERMODS=!_FNISFOLDERMODS:FNISTEMP=\!

IF !FNISFOLDERMODS!==!_FNISFOLDERMODS! (
SET FNISTEMP=!_FNISFOLDERMODS!
) else (
SET FNISTEMP=!FNISFOLDERMODS!
)
set FNISFOLDER=!FNISTEMP:\tools\GenerateFNIS_for_Mods=\!

:FNISCOMPARE
IF /I NOT "!SKYRIMFOLDER!\Data\"=="!FNISFOLDER!" (SET MOINSTALLED=YES)


cd /d %CURRDRIVE%:\
cd !FNISFOLDER!
cls

echo(
echo _______________________________......Processing for %USERNAME%......__________________________________
echo(
echo(
echo(
echo(
@echo off




set "logFile=C:\Users\%USERNAME%\Documents\My Games\Skyrim\Logs\FNISREMOVE.log"
REM Recycle log if too large
set /A TESTVAL=%FNISDRIVE% * 3000
for %%a in ("%logFile%") do if %%~za gtr TESTVAL (
type nul > "%logFile%"
)
if exist "%logFile%" (set "operator=>>") else (set "operator=>")
set "log=%operator% "%logFile%""
%log% (
echo Start time is: %date% %TIME%
@echo on

SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\behaviors\0_master.hkx"
IF EXIST !FNISTEMP! (
del /F /S /Q "!FNISTEMP!"
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\behaviors\mt_behavior.hkx"
IF EXIST !FNISTEMP! (
del /F /S /Q "!FNISTEMP!"
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\behaviors\FNIS*.hkx"
IF EXIST !FNISTEMP! (
del /F /S /Q "!FNISTEMP!"
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\characters\defaultmale.hkx"
IF EXIST !FNISTEMP! (
del /F /S /Q "!FNISTEMP!"
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\characters\female\defaultfemale.hkx"
IF EXIST !FNISTEMP! (
del /F /S /Q "!FNISTEMP!"
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\animationsetdatasinglefile.txt"
IF EXIST !FNISTEMP! (
del /F /S /Q "!FNISTEMP!"
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!FNISspell.esp"
IF EXIST !FNISTEMP! (
del /F /S /Q "!FNISTEMP!"
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)

SET "FNISTEMP=!FNISFOLDER!Meshes\AnimObjects\FNIS"
IF EXIST !FNISTEMP! (
RD /S /Q "!FNISTEMP!"
REM RD does not echo deletion confirmation
echo "!FNISTEMP!" directory should be removed.
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\animations\FNIS"
IF EXIST !FNISTEMP! (
RD /S /Q "!FNISTEMP!"
echo "!FNISTEMP!" directory should be removed.
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\animations\FNISBase"
IF EXIST !FNISTEMP! (
RD /S /Q "!FNISTEMP!"
echo "!FNISTEMP!" directory should be removed.
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Meshes\actors\character\animations\FNISSpells"
IF EXIST !FNISTEMP! (
RD /S /Q "!FNISTEMP!"
echo "!FNISTEMP!" directory should be removed.
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Tools\GenerateFNIS_for_Modders"
IF EXIST !FNISTEMP! (
RD /S /Q "!FNISTEMP!"
echo "!FNISTEMP!" directory should be removed.
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)
SET "FNISTEMP=!FNISFOLDER!Tools\GenerateFNIS_for_Users"
IF EXIST !FNISTEMP! (
RD /S /Q "!FNISTEMP!"
echo "!FNISTEMP!" directory should be removed.
) else (
echo "!FNISTEMP!" could not be found so not deleted.
)

REM Some problem with FNIS file deletions?
if '%errorlevel%' NEQ '0' goto ENDSCRIPT

)
@echo off
set /A FNISDRIVE=FNISDRIVE+1
:INCREMENTDRIVE


if %CURRDRIVE%==B (
set CURRDRIVE=C
GOTO SEARCHDRIVES)
if %CURRDRIVE%==C (
set CURRDRIVE=D
GOTO SEARCHDRIVES)
if %CURRDRIVE%==D (
set CURRDRIVE=E
GOTO SEARCHDRIVES)
if %CURRDRIVE%==E (
set CURRDRIVE=F
GOTO SEARCHDRIVES)
if %CURRDRIVE%==F (
set CURRDRIVE=G
GOTO SEARCHDRIVES)


:FINISH

color 1E


IF DEFINED MOINSTALLED (
echo(
echo TES Data directory contents have likely moved to a MO dir. andor there exists a backup drive.
echo(
)


echo(
IF %FNISDRIVE% EQU 1 (
echo Success: FNIS remnants removed on exactly one drive. Log opens with Notepad if no viewer associated.
) else (
echo Success: FNIS remnants removed on more than one drive. Log opens with Notepad if no viewer associated.
)
echo(


:PROMPTFINISH

SET "validateText="
SET /P validateText="Type S to delete script, L to delete log, A to delete script and log, K to keep all. (S/L/A/K)"


if /i !validateText!==S (
FOR /F "Tokens=1 delims=," %%G IN ('ASSOC .log') DO (@Set ASSOCLOG=%%G)
if DEFINED ASSOCLOG ("%LOGFILE%"
) else (start "" notepad "%LOGFILE%")
call :deleteSelf
goto :eof)

if /i !validateText!==L (
If EXIST "%logFile%" (del "%LOGFILE%" /F /S /Q)
goto :eof)

if /i !validateText!==A (
If EXIST "%logFile%" (del "%LOGFILE%" /F /S /Q)
call :deleteSelf
goto :eof)

if /i !validateText!==K (
FOR /F "Tokens=1 delims=," %%G IN ('ASSOC .log') DO (@Set ASSOCLOG=%%G)
if DEFINED ASSOCLOG ("%LOGFILE%"
) else (start "" notepad "%LOGFILE%")
goto :eof)

GOTO :PROMPTFINISH

:ENDSCRIPT
color C0

ECHO  (^G)
cls
@echo off
echo(
echo(
echo(
echo                        Some or all of the FNIS remnant files were not removed at this time.
echo(
pause >nul
EXIT /b 0
endlocal
:deleteSelf
start /b "" cmd /c del /F /Q "%~f0"&exit /b

Re: The contorted Logic of Dir & For/D

Posted: 14 May 2015 08:01
by lmstearn
Just curious regarding the way Win 8 assigns drives on the machine running this code.
For no disks in each E,F,G we get "continue, try again, cancel" message boxes generated by the system.
These cannot be touched using Computer Management.
It's strange as my current assignments are
C:NTFS
D:DVD
I:NTFS
J-M: Flash Drives
Know of any reason H has been made unavailable? No way to suppress the messages on EFG?

Re: The contorted Logic of Dir & For/D

Posted: 15 May 2015 05:34
by lmstearn
Aha, it's a quirk or misconfiguration of how the removable media is organized on this machine. The second NFTS drive was added prior to upgrading from XP to 7. There was a problem with the system automatically assigning a drive letter to the second NTFS drive at that time as it was still under the "control" of the previous OS. It should have been added as drive D before the CD was installed.

So for some reason this has disrupted the pool of removable drives. Inserting the first USB stick won't allocate the E: label. Instead it will be assigned to J: Thus E,F,G have become ghost drives, permanently awaiting media which will never be assigned.
This has also affected programs like ENB running with ES Oblivion.
http://enbdev.com/enbseries/forum/viewt ... 01f#p53387
Ran the excellent DriveCleanup.exe from Sieber tools which appeared to clear up quite a lot of drive problems. It may require a reboot to see exactly what.
In any case, let's hope the OS doesn't require a clean install to resolve the issue.

Heck this sort of stuff belongs to super user or such, but maybe it's of value to someone here. Will edit this post for any developments. :)

Re: The contorted Logic of Dir & For/D

Posted: 15 May 2015 06:25
by Squashman
Hmm, I have no idea how a previous install of XP could affect your current install of Windows 7. There is not true upgrade path from XP to Windows 7. You can only do a clean install.

Re: The contorted Logic of Dir & For/D

Posted: 15 May 2015 06:57
by lmstearn
The second NFTS disk might have had old XP MFT corrupted stuff on it. The W7 didn't grab it properly and was renamed from H to I after installing Win 8. Years ago now. :?