Одно из самых жутких, заброшенных и тоскливых мест Windows - это управление приложениями. Целиком мне сейчас о нём говорить не хочется, скажу только об одном аспекте: об анинсталле. Как он устроен - это дичайший бред. Попробуйте удалить несколько случайных продуктов на системе, которая проработала пару лет!
Не найден msi-файл установки, удаление невозможно.
Пропал компонент приложения, удаление невозможно.
Кто-то перезаписал мою регистрацию, удаление невозможно.
Кто-то вручную удалил с диска файлы, удаление невозможно.
(далее)Это бред сумасшедшего. Как это удаление может быть невозможно?! Мне нужно не установить, а удалить! Слышите - удалить! Программу. Просто взять и удалить. Неужели это так сложно? Неужели для удаления файлов действительно требуется, чтобы они все до единого были на месте, чтобы сохранился пакет установки программы?
Да нет конечно же! Это лентяи-программисты заставляют пользователей плясать под свою дудку. Вместо того, чтобы подумать головой и написать нормальный деинсталлятор, они предпочитают переваливать все проблемы на плечи пользователя. Нет уверенности, что мы удалим всё? Ну так не будем удалять ничего! Пусть пользователь сам разбирается.
Удаление, уничтожение, очистка - это операции, которые должны выполняться "наилучшим возможным образом". Т.е. в каждой ситуации должен удаляться абсолютный максимум того, что можно удалить. Если каких-то файлов уже нет - удаляем те, что остались. Если установочного пакета нет - ладно, удаляем хотя бы то, о чём сохранились записи. Не сохранилось записей - удаляем хотя бы то, о чём можно догадаться без них.
Ошибок в этих операциях не должно существовать в принципе. Они должны выполняться всегда.
В качестве бонуса: этот же принцип относится и к деструкторам объектов в программировании. Деструктор должен работать всегда. В каком бы состоянии не находился объект, деструкция, деинициализация, и вообще всё, что угодно, с приставкой "де-", должно игнорировать ошибки и удалять всё возможное.
Это не значит, что надо ловить в деструкторе все ошибки и затыкать им рты. Если ошибка уже случилась, её, как обычно, нужно вывести пользователю. Просто деструктор должен быть написан так, чтобы выполнять максимум без ошибок даже в неизвестных обстоятельствах. Например, даже если деструктор у вас вызывается единожды, и lpMyObject всегда существует, нужно писать:
if (lpMyObject != NULL) {
FreeMyObject(lpMyObject);
lpMyObject = NULL;
}
Хорошая практика - это чтобы ваш деструктор можно было вызвать на любом этапе жизни объекта, и он успешно выполнился бы. Даже в середине конструктора. Даже в процессе выполнения какой-то критической функции. Потому, что деструктор не может позволить себе вызывать исключения: его самого, вероятно, вам придётся вызывать, если вы надеетесь программно обработать какие-то исключения. Следовательно, деструктор уже должен быть готов обрабатывать исключительные ситуации.
А мы, люди советской закалки, делаем по рабоче-крестьянски: ставим систему со всем нужным софтом, настраиваем всё что надо, и записываем образ. Чуть что не так /обычно по истечению срока от двух месяцев до двух-трёх кварталов/ - форматим и разворачиваем систему. Обычно минут за 10-15.
Загибаю пальцы - опен офис, текстовый редактор, почтовый клиент, 3 броузера, 2 видеоплеера, 1 аудио, фотошоп, программа просмотра изображений, 3 мессенгера, карта города с бд, торрент, эверест и ещё несколько подобных программ, японо-русский словарь, антивирус, файрвол, ну и ряд полезных утилит типа панто свитчера итд. Получается сколько-то десятков. Четыре. Ну или пять.
Вопрос - что тут может критично устареть?
Тут человек подсказал самый правильный принцим в подобных операциях, сформулированный еще Гоголем в "Тарасе Бульбе" =)... хотя тут же назвал пару исключений из правила.
все-таки когда мелкософт сделает свою систему с зависимостями и компонентную модель с блекджеком и шлюхами?) говорят, пишут, вроде...