#windows
Я вот вижу (по своему реестру), что все деинсталяторы лежат в папках, которые они удаляют. Но если попробовать сделать thisDir.Delete(true /*recursively*/), то вылетит exception Access to the path 'uninstaller.exe' is denied. Ведь нельзя удалить файл, который выполняется. Есть вариант, что uninstaller может создать исполняемый файл (tmpUninstaller.exe) в какой-то временной директории, запустить его, tmpUninstaller.exe ждёт когда завершится оригинальный uninstaller, зачищает всё и самоудаляется. Но, как по мне, это костыльный вариант решения поставленной задачи. Как же всё-таки uninstaller удаляет директорию в которой он находится?
Ответы
Ответ 1
Есть вариант, что uninstaller может создать исполняемый файл (tmpUninstaller.exe) в какой-то временной директории, запустить его, tmpUninstaller.exe ждёт когда завершится оригинальный uninstaller, зачищает всё и самоудаляется. Правильно мыслите Вот полная строка события из Process Monitor: 8:26:29,1260988 unins000.exe 20396 Process Create C:\Users\8CE3D~1\AppData\Local\Temp\_iu14D2N.tmp SUCCESS PID: 9672, Command line: "C:\Users\8CE3D~1\AppData\Local\Temp\_iu14D2N.tmp" /SECONDPHASE="C:\Program Files (x86)\SHTRIH-M\DrvFR 4.13\unins000.exe" /FIRSTPHASEWND=$3B1228 /INITPROCWND=$680CC6 Есть и другие способы создания самоудаляющейся программы: Самоудаление программы Но, как по мне, это костыльный вариант решения поставленной задачи. Как же всё-таки uninstaller удаляет директорию в которой он находится? Инсталлятор программы в примере выше сделан с помощью Inno Setup, которая не использует модель Windows Installer. Для инсталляторов, основанных на модели Windows Installer, необходимости в деинсталляторе как таковом вообще нет. При установке такой программы Windows Installer сохраняет ее MSI-пакет в каталоге c:\windows\installer. Для удаления программы достаточно вызвать msiexec с нужными параметрами, он загрузит сохраненный MSI, выполнит удаление, а затем удалит MSI.Ответ 2
В дополнение к ответу от @MSDN.WhiteKnight стоит упомянуть полезную функцию WinAPI MoveFileEx с флагом MOVEFILE_DELAY_UNTIL_REBOOT. В принципе, одной этой функции достаточно для удаления, и некоторые инсталляторы ее и используют для самоудаления анинсталлера. Проблема с ней только в том, что каталог программы при этом не удаляется (что мы и видим у некоторых приложений). Для полного удаления вместе с каталогом используется двухступенчатый процесс, как описано в предыдущем ответе: Записать в Temp программу (или батник) удаления. Запустить ее, при этом удалялка должна уметь дожидаться выхода запустившего ее анисталлера. Вызвать MoveFileEx(szDeleterPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); для удаления после рестарта системы удалялки из Temp. Выйти. Вместо вызова MoveFileEx можно удалять через реестр. Для этого в HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce нужно создать текстовое значение с произвольным именем (например, DeleteMyApp), и строкой cmd /C del "путь_к_программе_удаления". При следующем рестарте Windows выполнит эту команду и удалит это значение из реестра.
Комментариев нет:
Отправить комментарий