Избегайте перевода MSI в режим совместимости "Предыдущая версия Windows"
У меня есть установочный пакет для 32-разрядного приложения (созданного с помощью MakeMsi, первоначально для Windows XP, и с тех пор упрощенно поддерживаемого), который не может зарегистрировать COM-сервер в современных (64-разрядных) системах Windows (7, 8, 10), Вот что я вижу, когда пытаюсь установить мой MSI нормально:
Ошибка приложения
Исключение EOleSysError в модуле xyz на 000F0B01. Ошибка доступа к реестру OLE.
Если я перевожу MSI в режим совместимости Предыдущая версия Windows, COM-сервер успешно регистрируется. Так как "это работает" каким-то образом, я до сих пор не уделял много времени изучению причин. Но, наконец, я устал вспоминать наших клиентов (а иногда и меня) снова и снова об этом предварительном условии, поэтому я хочу решить эту проблему.
Регистрация (и отмена регистрации) осуществляется через CustomAction s, как я смотрю, используя Orca:
"[INSTALLDIR.MYAPP]\placeholder.exe" -regserver
"[INSTALLDIR.MYAPP]\placeholder.exe" -unregserver
Для каждой из этих записей Type
является 1122
а также Source
является INSTALLDIR.MYAPP
,
Я мог бы представить, что COM-сервер запускается с недостаточными привилегиями в процедуре установки, но разве установщики не запускаются автоматически с правами администратора? Я имею в виду, что когда я (как обычный пользователь) запускаю установщик, дважды щелкнув по нему, он показывает приглашение UAC до того, как будет произведена фактическая установка. Почему COM-серверы не работают с повышенными правами для их регистрации и отмены регистрации? Это сбивает с толку...
Как изменить MSI, чтобы программа установки Windows успешно его обработала?
2 ответа
Узнав, как правильно регистрировать COM-серверы, мне все же было интересно понять, почему мой MSI-пакет работал раньше. Другими словами: что является принципиальным изменением после Windows XP?
... Я также проверил, что MSI работает, когда я запускаю его как администратор...
Как я выяснил, читая документацию по инструментам WiX, есть атрибут Impersonate
за CustomAction
это контролирует, если CA выполняется с повышенными привилегиями:
Этот атрибут указывает, должен ли установщик Windows, который выполняется как LocalSystem, олицетворять пользовательский контекст устанавливающего пользователя при выполнении этого настраиваемого действия. Обычно значение должно быть "да", за исключением случаев, когда настраиваемое действие требует повышенных привилегий для применения изменений к компьютеру.
Это относится к msidbCustomActionTypeNoImpersonate
флаг в Type
поле CustomAction
Таблица Значение 1122
Я заметил, что мой MSI декомпилирован в это:
- 1024 (флаг): msidbCustomActionTypeInScript или отложенное выполнение выполняется в сценарии установки
- 64 (флаг): msidbCustomActionTypeContinue или игнорировать код выхода и продолжить
- 34: Тип настраиваемого действия 34 или запустить исполняемый файл из командной строки
То, что я использовал, чтобы "исправить" проблему быстрым способом, включить msidbCustomActionTypeNoImpersonate
флаг (2048
) в типе CA (в WiX это будет Impersonate="no"
).
Переведенный в мой скрипт MakeMsi, я должен был использовать System
атрибут в Type
из ExeCa
команда как сделать саморегистрацию работает как раньше:
Type="Deferred Sync AnyRc System"
Я полностью осознаю, что это только обходной путь, поскольку запуск COM-сервера для (не) регистрации опасен. И поэтому решение, упомянутое во втором разделе ответа PhilDWs, должно быть предпочтительным: управлять статической информацией, связанной с COM, через записи реестра в MSI. Но иногда вам нужно быстрое решение, а иногда нет другого выхода, см. Комментарий Euro Micellis.
Я предполагаю, что вы знаете, что проблема в исполняемом файле, который вы запускаете как пользовательское действие, а не в установщике Windows. Это означает, что проблема заключается в коде в исполняемом файле, и он, вероятно, старый и несовместим с более поздними версиями ОС. Вам нужно будет посмотреть на код, чтобы увидеть, что он делает, что не поддерживается.
Многие установки не заботятся о самостоятельной регистрации. Эти данные - все статические данные, которые можно извлечь один раз и включить в файл MSI в записи реестра и другие таблицы классов COM. Это означает, что нет необходимости запускать код во время установки.