Как рекурсивно удалить содержимое каталога без удаления определенного подкаталога

Я пишу программу установки / удаления в NSIS для своей игры. Моя игра поддерживает пользовательские моды, и я хочу дать возможность удалять пользовательские моды во время деинсталляции или нет. А теперь самое сложное: моды помещаются в подкаталоги $INSTDIR. Поэтому, если у пользователя есть какие-то моды, которые нужно сохранить, я хочу удалить все, что находится рядом с этим каталогом подмодов (поэтому я не могу использовать простой старый RMdir /R).

Файлы, которые я хочу сохранить, имеют такую ​​структуру:

$INSTDIR/Modules/[anything-but-Base]
$INSTDIR/Modules/Base/Submod

Например, если пользователь решил сохранить свои моды, я хочу сохранить каталоги:

$INSTDIR/Modules/Base/Submod/Sample1
$INSTDIR/Modules/Base/Submod/Sample2
$INSTDIR/Modules/Base/Submod
$INSTDIR/Modules/Sample3
$INSTDIR/Modules/Sample4

И удалите из $INSTDIR все остальное, включая пустые каталоги

Я пробовал сделать что-то подобное:

FindFirst $R0 $R1 "$INSTDIR\Modules\Base\*.*"
Loop:
    StrCmp $R1 "" Done
    StrCmp $R1 "Submod" DeleteSubMods
    Goto DeleteCoreMod
    DeleteSubMods:
        RMdir "$INSTDIR/Modules/Base/Submod" ; Remove only if empty
        Goto FindNextItem
    DeleteCoreMod:
        RMdir /R "$INSTDIR/Modules/Base/$R1" ; Remove always
    FindNextItem:
    FindNext $R0 $R1
    Goto Loop
Done:
FindClose $0

RMdir "$INSTDIR/Modules/Base" ; Only if empty
RMdir "$INSTDIR/Modules" ; Only if empty

FindFirst $R0 $R1 "$INSTDIR\*.*"
Loop2:
    StrCmp $R1 "" Done2
    StrCmp $R1 "Modules" FindNextItem2 ; Remove everything but Modules
        RMdir /R "$INSTDIR/$R1"
        Delete "$INSTDIR/$R1"
    FindNextItem2:
    FindNext $R0 $R1
    Goto Loop2
Done2:
FindClose $0

Но он не дает мне правильных результатов (он оставляет пустой каталог $ INSTDIR / Modules и удаляет все остальное)


person PiotrK    schedule 09.04.2014    source источник


Ответы (2)


Как насчет удаления только ваших файлов?

Полагаю, при установке вы делаете что-то вроде A)

SetOutDir $INSTDIR
File "*.*"

Как насчет создания списка всех файлов по одному B)

SetOutDir $INSTDIR
File "1"
File "2"
File "3"
File "4"
File "n"

В случае Б) создайте такой же список для деинсталлятора (в разделе «Удаление»). Таким образом, будут удалены только ваши файлы, а файлы модов останутся нетронутыми.

Используйте RMdir (без / r) для удаления каталогов - они будут удалены, только если они полностью пусты, поэтому ваши моды будут сохранены.

И последний вопрос: разве без игры моды бесполезны? Думаю, не подействуют ...

person Slappy    schedule 10.04.2014
comment
Все мои ресурсы хранятся в виде простых данных (png / ogg / xml), поэтому для установки потребуется множество отдельных файлов. Не говоря уже о патчах, которые могут добавлять файлы, которые также необходимо удалить во время деинсталляции. И реальная деинсталляция также дает возможность удалять файлы модов, я просто не хочу раздражать пользователя, молча принудительно удаляя файлы, которые он / она может собрать из различных интернет-источников и хочет сохранить их / перенести на другой компьютер. - person PiotrK; 10.04.2014
comment
Затем сделайте резервную копию папки модов в каталог $ TEMP, удалите все с помощью RMDir / r и скопируйте / создайте папку обратно. - person Slappy; 11.04.2014

Вот это: http://nsis.sourceforge.net/Delete_dirs_/_files_in_a_directory_except_one_dir_/_file фрагмент в вики NSIS, я смог адаптировать его для собственного использования (забыл о вики NSIS). В основном основные проблемы заключались в том, что я использовал взаимозаменяемые / и \, и они НЕ ИМЕЮТ того же значения в NSIS.

person PiotrK    schedule 10.04.2014