Хобрук: Ваш путь к мастерству в программировании

Поиск и удаление временных файлов/папок (сбой скрипта)

Я использую этот сценарий для очистки истории, файлов cookie и кеша (временных файлов Интернета) для всех пользователей, И он также должен очистить временный каталог, НО, похоже, что-то не так.

Я думаю, что смешиваются две вещи: переменная %temp% (= D:\TEMP в моей среде) И временный каталог пользователей в каталоге %userprofile%.

:: Works on Win XP  -and-  on Win 7

@echo off

Set "RegKey=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
set "regkey2=HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\shell folders"

call:getspecialfolders "Cache, History, Cookies"

For /f "tokens=*" %%? in (
 'Reg.exe QUERY "%RegKey%" ^|findstr /ric:"\S-1-5-21-[0-9]*-[0-9]*-[0-9]*-[0-9]*$"'
 ) do (
 For /f "tokens=2,*" %%A in (
 'Reg.exe QUERY "%%?" /v ProfileImagePath ^|find /i "ProfileImagePath"'
 ) do call:Go %%B
)

start ""/w "%windir%\system32\RunDll32.exe" InetCpl.cpl,ClearMyTracksByProcess 255

:end ***


goto:EOF
:Go
   call Set "Target=%*"
   If EXIST "%Target%" call:Clear "%Target%"
exit /b 0

:Clear
REM echo.&echo.%~1\%$$Cache%
   pushD "%~1\%$$Cache%" &&(
   rmdir /S /Q .
   popD)2>C:\test1_TEMP_IE.txt

REM echo.&echo.%~1\%$$History%\History.IE5
REM    pushD "%~1\%$$History%\History.IE5" &&(
REM    rmdir /S /Q .
REM    popD)2>C:\test1_History_IE.txt

REM echo.&echo.%~1\%$$History%
   pushD "%~1\%$$History%" &&(
   rmdir /S /Q .
   popD)2>C:\test1_History.txt

REM echo.&echo.%~1\%$$Cookies%
   pushD "%~1\%$$Cookies%" &&(
   rmdir /S /Q .
   popD)2>C:\test1_Cookies.txt

ECHO.&echo.%~1\%$$temp%
   pushD "%~1\%$$temp%" &&(
   rmdir /S /Q .
   popD)2>C:\test1_Temp.txt
exit /b 0

:getspecialfolders
   Set "FoldersToClear=%~1"

   For %%* in (%FoldersToClear%) Do (
     For /f "tokens=2,*" %%A in (
     'reg.exe query "%regkey2%" /v %%* ^|find /i "%%~*"'
     ) do Call:sf1 "%%~B" "%%~*"
   )
   Call:sf2 "%temp%" "temp" "%userprofile%"
exit /b 0

:sf1
   Call set "sf=%~1"
   Call set "$$%~2=%%sf:%userprofile%\=%%"
exit /b 0

:sf2
   Call set "sf=%~1"
   call Set "usr=%~dpns3"
   Call set "$$%~2=%%sf:%usr%\=%%"
exit /b 0

НО почему-то я не могу заставить последнюю «временную часть» работать, поэтому она очищает% temp% (D: \ Temp в моей среде), а также находит все «temp dir's» в% userprofile%.

т.е. это, например, работает для %temp%:

PushD "%Temp%" && (
ATTRIB -S -H -R -A /D /S & (
For /f "Tokens=*" %%* in ('dir "%Temp%" /B') Do (
RD "%Temp%\%%*" /S /Q || Del /F /S /Q "%Temp%\%%*"))&PopD)2>c:\test0b_TEMP.txt

и это, т.е. работает для "временных пользователей":

::Set Search directory to "Documents and Settings" folder
(Set Target=%AllUsersProfile:~0,-10%)

title,Finding the Temp subfolders in %Target%&COLOR 9E

If EXIST "%Target%",(
  For /f "Tokens=*" %%* in ('dir "%Target%" /B') Do (
   cd/D "%target%\%%*\Local Settings\Temp" && (
   ATTRIB -S -H -R -A /D /S >nul & (
  For /f "Tokens=*" %%* in ('dir /B') Do (
   RD "%%*" /S /Q ||Del /F "%%*" )))>nul)
 )

Я надеюсь, что кто-нибудь может помочь мне исправить скрипт, я думаю, что он находится в: sf2 и / или в сочетании с частью% temp%, теперь как-то смешиваются две вещи ("users temp" и "environment temp") .


Ответы:


1

Хорошо, на этот раз я думаю, что есть способ исправить это, а именно, добавив проверку, содержит ли переменная относительный или абсолютный путь, непосредственно перед продолжением очистки. Идея состоит в том, чтобы проверить наличие двоеточия (:) в строке. Если присутствует двоеточие, путь не мог быть преобразован в относительный путь ранее, и поэтому его следует использовать как есть, без предварительной обработки пути к профилю, в противном случае путь к профилю должен быть присоединен перед продолжением.

Вот базовый пример, который вы можете протестировать и поиграть, если хотите:

@ECHO OFF
SET somepath=D:\TEMP
CALL :checkpath
SET "somepath=Local Settings\Temp"
CALL :checkpath
PAUSE
GOTO :EOF

:checkpath
IF "%somepath%"=="%somepath:*:=%" (ECHO Relative path) ELSE ECHO (Absolute path)

В вашей конкретной ситуации я бы, вероятно, применил такой метод:

вместо

…
ECHO.&echo.%~1\%$$temp%
   pushD "%~1\%$$temp%" &&(
   rmdir /S /Q .
   popD)2>C:\test1_Temp.txt
…

я бы попробовал

…
IF "%$$temp%"=="%$$temp:*:=%" (SET "tmppath=%~1\%$$temp%") ELSE SET "tmppath=%$$temp%"
ECHO.&echo.%tmppath%
   pushD "%tmppath%" &&(
   rmdir /S /Q .
   popD)2>C:\test1_Temp.txt
…

Как видите, временная переменная используется для хранения фактического пути для обработки. Я понимаю, что достаточно заменить только часть, где очищается временная папка, но вы можете видеть, что этот метод может быть легко применен и к другим папкам, если это необходимо.

09.09.2011
  • Андрей М, ГЕРОЙ (моего) дня ;-p 09.09.2011
  • (выдает ошибку/сообщение, когда каталоги пусты, почему?) 12.09.2011
  • Не уверен, о чем именно вы говорите. Если вы имеете в виду ошибку при выполнении rmdir /S /Q ., то она возникает не только на пустых каталогах, а каждый раз (на Win 7 по крайней мере). rmdir пытается удалить текущую директорию (.) со всем ее содержимым и жалуется, что не может этого сделать (удалить текущую директорию), что вполне справедливо, так как система запрещает удалять активную (текущую) папку. 12.09.2011
  • Это была не "моя" ошибка. То, что я получил, было связано с эффектом «Процесс не может получить доступ к файлу, потому что он используется другим процессом» (извините, я не уверен, что это точный английский эквивалент, оригинал был на русском языке). Так что, хм... действительно странно. 13.09.2011
  • мне просто кажется странным, что возвращается ошибка: , Система не может найти указанный путь ''. Вероятно, потому что он пытается удалить текущий каталог, как вы только что упомянули. Сценарий удаляет файлы/каталоги в указанном каталоге (если только файл не используется), поэтому эта часть работает нормально. Возможно, есть способ подавить указанную выше ошибку/сообщение? 13.09.2011
  • да, когда я читаю файлы журнала, созданные сценарием, я вижу некоторые ошибки из-за файлов, которые используются системой, эти ошибки/сообщения действительно подавляются, вышеуказанная ошибка/сообщение по-прежнему отправляется на экран (как вы можете видеть здесь, URL: img199.imageshack.us/img199/9127/errorif.jpg) 13.09.2011
  • Ошибки обычно выводятся на так называемое устройство стандартной ошибки, в отличие от стандартного вывода, который используется для «нормального» вывода. Стандартный вывод можно подавить с помощью >NUL, а стандартный вывод с помощью 2>NUL. 13.09.2011
  • конечно, я попробую ›nul вместо 2››C:\an_error_file_name.txt и посмотрю, все ли подавлено, чем 13.09.2011
  • Ошибка cannot find the path может быть вызвана некоторыми командами PUSHD, если есть попытка переключиться на несуществующий каталог. Тогда хорошо, что есть &&, который связывает PUSHD со следующим блоком и не позволяет ему выполняться, когда PUSHD терпит неудачу. 13.09.2011
  • странно, что все каталоги ДЕЙСТВИТЕЛЬНО существуют. 13.09.2011
  • изменение 2› на ›nul усугубляет ситуацию, теперь появляется много ошибок ,,file in use, :'( I хотел бы, чтобы все выходные данные каким-то образом подавлялись 13.09.2011

  • 2

    Похоже, ваша подпрограмма sf2 пытается получить относительный путь к папке Temp, отрезая начало пути, который по сути является путем к профилю пользователя:

    Call set "$$%~2=%%sf:%usr%\=%%"
    

    где sf содержит временную папку, а usr профиль пользователя. Таким образом, вместо, например, C:\Documents and Settings\APOC\Local Settings\Temp вы получите просто Local Settings\Temp.

    Но есть проблема. Хотя переменной sf назначается правильный путь, переменной usr, с другой стороны, по какой-то причине назначается вариант с коротким именем пути к профилю пользователя. То есть вместо чего-то вроде C:\Documents and Settings\APOC получает что-то вроде C:\DOCUME~1\APOC. Вот оскорбительная строка:

    call Set "usr=%~dpns3"
    

    Таким образом, когда ранее указанная строка выполняется, ожидаемая замена никогда не происходит, потому что C:\Documents and Settings\APOC, естественно, не соответствует C:\DOCUME~1\APOC. В результате переменная $$temp заканчивается полным путем, а не относительным путем, и из-за этого соответствующие части вашего кода, которые ссылаются на $$temp, не выполняют свою работу должным образом.

    Короче говоря, я думаю, что вам вообще не нужна эта процедура sf2. Подпрограмма sf1, по-видимому, делает то же самое, что и sf2, только с другим набором передаваемых параметров. Итак, вместо

    Call:sf2 "%temp%" "temp" "%userprofile%"
    

    Я предлагаю вам попробовать это:

    Call:sf1 "%temp%" "temp"
    
    08.09.2011
  • вот что я получил/получил со своим скриптом (пока ничего не изменилось): C:\Documents and Settings\admin-lksvdd\D:\TEMP 09.09.2011
  • Я вижу, я не учел "нестандартный" D:\TEMP путь... Подскажите, пожалуйста, в чем смысл этой цепочки действий: сначала получить путь к специальной папке, потом отрезать начальную часть (тот, который соответствует пути к профилю), только чтобы позже снова вернуться к полному пути, присоединив путь к профилю там, где он был изначально? Я сначала думал, что относительные пути получаются только один раз, потом к ним по очереди применялись все профильные пути. Если это не так, то есть если скрипт всегда очищает только специальные папки текущего пользователя, я думаю, вам следует просто пропустить этот дополнительный этап. 09.09.2011
  • Не уверен, это старый скрипт, который я позаимствовал из кеша Google (владелец / разработчик скрипта не реагирует), поэтому я попробовал его здесь. Он действительно также очищает несколько пользователей, однако, см. запрос, используемый в ProfileImagePath, эта строка обнаруживает/находит всех активных пользователей. Вызов: sf2 %temp% temp %userprofile% для CurrentUser (только? насколько мне известно) И PROfileImagePath QUERY для поиска активных пользователей. 09.09.2011
  • Использовалась временная среда Windows по умолчанию, и она снова работает: %UserProfile%\Local Settings\Temp (для текущего пользователя) и %SystemRoot%\Temp ( системная переменная). Теперь, как исправить скрипт, чтобы он все еще работал, когда не используются никакие значения по умолчанию для Windows ... Вот когда все идет ужасно неправильно :-( 09.09.2011

  • 3

    Я немного изменил строку для temp, это правильный путь? (он работает, но правильно ли он отформатирован?)

    IF "%$$temp%"=="%$$temp:*:=%" (SET "tmppath=%~1\%$$temp%") ELSE SET "tmppath=%$$temp%"
    ECHO.&echo.%tmppath%
       pushD "%tmppath%" &&(
       ATTRIB -S -H -R -A /D /S & (
       rmdir /S /Q . || Del /F /S /Q .
       )&popD)2>C:\test1_Temp.txt
    

    + Дополнительный "Del /f /s /q" для возможных жестких файлов/файлов только для чтения (и дополнительный атрибут)

    Кстати Кажется, что-то все еще не работает на 100% в сценарии с "temp"-частью, я изменил свои временные настройки по умолчанию в Windows на пути по умолчанию для целей тестирования, и я получаю эти 3 ошибки : скриншот ошибки | URL: http://img199.imageshack.us/img199/9127/errorif.jpg

    script запускается с временным путем Windows по умолчанию:

    [пользователь] %UserProfile%\Local Settings\Temp и [система] %SystemRoot%\Temp

    Я не уверен, почему я получаю эти ошибки, когда я устанавливаю для обоих временных параметров значение D:\TEMP, я получаю 3 раза одну и ту же ошибку, но чем для D:\TEMP вместо доступных/активных пользователей \local settings\Temp . Возможно проблема в локалах~1??? (Хотя временные каталоги очищаются, но почему он говорит, что не может найти путь?)

    09.09.2011
  • Проблема НЕ возникает, когда каталоги заполнены файлами, поэтому указанная выше ошибка возникает только тогда, когда каталоги пусты. Как получилось/почему? Можно ли это предотвратить или скрыть эти сообщения? (что ничего не нашли) 12.09.2011
  • Новые материалы

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

    Как я опубликовал свое первое приложение в App Store в 13 лет
    Как все началось Все началось три года назад летом после моего четвертого класса в начальной школе. Для меня, четвертого класса, лето кажется бесконечным, пока оно не закончится, и мой отец..

    Что в лицо
    Очерк о возвращении физиогномики и о том, почему мы должны это приветствовать. История начинается со странной науки. Р. Тора Бьорнсдоттир, Николас О. Рул. Видимость социального класса по..

    Почему шаблоны проектирования и почему нет?
    Сложность — мать всех проблем в программировании. Программное обеспечение должно быть разработано с точки зрения того, кто его поддерживает, а не того, кто его пишет, потому что программное..

    Создание дизайна обуви с помощью машинного обучения
    Обувь. Что подождать? Я думал, что речь пойдет о машинном обучении! Ну это так. Если бы вы пошли на Amazon, сколько обуви вы бы нашли? Наверное, много, не так ли? Но много ли в них..

    GraalVM в 2022 году: итоги года
    2022 год был очень продуктивным для проекта и сообщества GraalVM. Вместе мы разработали множество новых функций, выпустили GraalVM для последних версий Java и новых платформ и увидели несколько..