Регистрация DLL CPP в COM после установки с помощью установщика Wix Msi
Я пытаюсь зарегистрировать библиотеку CPP в COM во время установки Msi.
Я много искал и нашел здесь много решений, но в моем коде ничего не работает. Я не знаю, есть ли прямой метод для этого. Я пытался использовать Custom Action с прямым ExeCommand и с пакетным скриптом.
Вот код с пакетным скриптом.
<SetProperty Id="Register" Value=""[INSTALLDIR]Scripts\Register.bat"" After="CostFinalize"/>
<CustomAction Id="Register" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/>
<SetProperty Id="Unregister" Value=""[INSTALLDIR]Scripts\UnRegister.bat"" After="CostFinalize"/>
<CustomAction Id="Unregister" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/>
Используя этот код, установка не показывает никаких ошибок, но dll не регистрируется. После установки, если я запускал пакетный скрипт отдельно, он регистрируется.
Register.bat
CD "C: \ Windows \ System32"
regsvr32 "C: \ Program Files (x86) \ ABC \ Abc.dll"
ping -n 15 127.0.0.1> nul:
Unregister.bat
CD "C: \ Windows \ System32"
regsvr32 / u "C: \ Program Files (x86) \ ABC \ Abc.dll"
ping -n 15 127.0.0.1> nul:
При использовании Custom Action с ExeCommand он показывает ошибку, например отсутствие некоторой зависимости dll. Код ExeCommand приведен ниже.
<CustomAction Id="Register" Directory="INSTALLDIR" Execute="deferred" Impersonate="no"
ExeCommand="[WindowsFolder]System32\regsvr32 "[INSTALLDIR]Abc.dll"" Return="check" />
<CustomAction Id="Unregister" Directory="INSTALLDIR" Execute="deferred" Impersonate="no"
ExeCommand="[WindowsFolder]System32\regsvr32 /u "[INSTALLDIR]Abc.dll"" Return="check" />
И InstallSequence для обоих случаев приведен ниже.
<InstallExecuteSequence>
<Custom Action="Register" Before="InstallFinalize" >NOT Installed</Custom>
<Custom Action="Unregister" Before="RemoveFiles">Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
</InstallExecuteSequence>
В обоих случаях я думаю, что он работает с повышенными привилегиями.
Это ошибка, которую я получаю большую часть времени.
редактировать
Зависимость ходунков от dll показана ниже.
Также я добавляю команду тепла, которую я использовал. Я добавил это к событию prebuild для генерации компонента. После этого добавили этот компонент в файл продукта.
вызвать файл "$(WIX)bin\heat.exe" "dllPath\Abc.dll" -dr "INSTALLDIR" -srd -gg -sfrag -suid -out "$(SolutionDir)Installer\ComRegisterComponent.wxs"
И сгенерированный файл выглядит следующим образом.
<Fragment>
<DirectoryRef Id="INSTALLDIR">
<Component Id="Abc.dll" Guid="*">
<File Id="Abc.dll" KeyPath="yes" Source="SourceDir\Abc.dll" />
</Component>
</DirectoryRef>
</Fragment>
Вот этот путь SourceDir сбивает меня с толку. Я добавил точный путь в команду Heat даже тогда, когда он генерирует этот SourceDir.
3 ответа
Краткий краткий ответ
Вам нужно прекратить использовать командные файлы и настраиваемые действия для регистрации COM (ненадежно) и вместо этого извлечь информацию о регистрации COM, используя инструмент heat.exe из инструментария WiX, чтобы добавить регистрацию COM в базу данных MSI во время компиляции.
Есть некоторые сложности для 64-битных двоичных файлов, подробности см. Ниже. К счастью, похоже, что вы имеете дело с 32-битным компонентом на основе вашего установочного каталога, показанного выше.
В данном конкретном случае это помогло запустить heat.exe для COM-файла после развертывания, когда все зависимости были "на месте" для правильной загрузки COM-файла. В этих ответах много "отладочной коммуникации" - я оставлю все это на будущее, но сначала попробую это простое решение. И, возможно, попробуйте новый инструмент зависимости "Dependencies.exe", описанный ниже.
Длинный, подробный ответ
Прежде чем я попытаюсь ответить на вопрос (который, кажется, вращается вокруг отсутствующих зависимостей или чего-то странного, что делается в вашем пакетном файле), я хочу прояснить для вас несколько вещей в отношении наилучшей практики регистрации COM.
Примечание. Снимок экрана, по-видимому, указывает на что-то странное, происходящее в вашем пакетном файле, но отсутствующие зависимости все еще могут быть проблемой.
Самостоятельная регистрация считается вредной
Самостоятельная регистрация не должна использоваться для регистрации COM-файлов. Вот описание того, почему это так: MSI register dll - Self-Registration считается вредоносной. Однако есть и хорошие новости: если вы настроите все правильно, то с помощью встроенных механизмов MSI все будет работать проще и надежнее.
Существует способ для самостоятельной регистрации файлов во время установки без использования пользовательских действий, как вы пытаетесь сделать ( таблица SelfReg). Пользовательские действия очень трудно заставить работать правильно, но вы не должны использовать встроенный механизм для запуска саморегистрации (как подробно описано в связанном ответе выше)
Вместо использования пользовательских действий или таблицы SelfReg регистрационную информацию COM следует извлекать из ваших COM-файлов во время компиляции - другими словами, когда вы компилируете MSI-файл из исходных файлов WiX. Извлеченные данные реестра следует использовать для заполнения семейства таблиц данных MSI, предназначенных для надежной регистрации и отмены регистрации файла COM во время установки и удаления соответственно.
WiX: инструмент командной строки "heat.exe"
Понимание сложных деталей этого процесса не является необходимым - все, что вам нужно знать, это какие инструменты использовать. WiX предоставляет инструмент " heat.exe " для этой цели. По сути, это инструмент " харвестера ", способный генерировать допустимые исходные файлы WiX XML для нескольких целей, одной из которых является извлечение COM. Он также поддерживает обход каталогов в целом - создание исходных файлов WiX, которые могут устанавливать файлы, обнаруженные во время обхода. По сути, это очень быстрый способ сделать пакет MSI, если вы знаете, как его использовать.
Зависимость Уокер
Итак, мы установили, что вы должны потратить время на то, чтобы узнать, как использовать heat.exe для создания источника WiX, необходимого для правильной регистрации COM-файла. Однако есть еще одна проблема: отсутствующие зависимости.
Для того чтобы COM-файл мог самостоятельно регистрироваться - или чтобы вы могли успешно извлекать данные реестра COM с помощью heat.exe - COM-файл должен загружаться правильно. Чтобы это было возможно, все зависимости dll должны быть доступны в рассматриваемой системе в доступном месте.
Получите копию Dependency Walker и используйте ее для сканирования вашего COM-файла на предмет того, от каких файлов он зависит. Вот пример файла COM, который не удается загрузить, потому что он не может найти MMUtilities.dll
:
Скорее всего, вы обнаружите что-то похожее не так с вашей DLL (или с любым другим типом файла, например, OCX), когда она запускается из места установки вашей установки. Regsvr32.exe не может найти требуемые файлы зависимостей, и процесс регистрации завершается неудачно.
Есть сообщения об отсутствующих зависимостях, которые не важны - я полагаю, что это связано с возрастом инструмента "Обход зависимости" - насколько я знаю, он недавно не обновлялся. Найдите файл, который вы опознаете как собственный файл зависимостей или как системный файл, в отличие от очень длинных имен файлов dll, о которых вы никогда не слышали. Имейте в виду, что некоторые библиотеки DLL содержат библиотеки языка зависимости, необходимые для загрузки. Например, MMUtilities.dll требует MmUtilitiesEnglish.dll или другую языковую библиотеку, присутствующую в той же папке, для корректной загрузки.
Некоторые примеры ложноположительных зависимостей для вышеуказанного файла: API-MS-WIN-CORE-RTLSUPPORT-L1-1-0.DLL
, API-MS-WIN-CORE-PROCESSTHREADS-L1-1-0.DLL
, API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL
и т.д... Их было много. Я верю, но я не уверен, что основная причина этих ложных срабатываний заключается в проблемах с параллельными компонентами, установленными в папку WinSxS, но это совсем другое обсуждение - просто упоминание об этом.
ОБНОВЛЕНИЕ: я только что проверил это снова, и большинство ложных положительных зависимостей, которые были видны выше, по - видимому, представляют собой наборы API - функция Windows, появившаяся задолго после создания Dependency Walker, и, следовательно, неправильно обработанная инструментом.
Как указывает связанный ответ (прочитайте его, ссылка выше), теперь есть также переписать Dependency Walker в C# под названием " Зависимости ", доступный здесь: https://github.com/lucasg/Dependencies (не проверенный мной в то время написания, скоро опробую).
Также быстрое упоминание: если у вас есть исполняемый файл для проверки (в отличие от dll, ocx и т. Д.), Вы можете запустить его через Profile => Start Profiling...
После входа в меню вы также увидите " скрытые зависимости времени выполнения ", не указанные в двоичной таблице импорта (где указаны зависимости / импорт). Вам нужно по-настоящему тренировать приложение, используя все функции во всех диалогах, чтобы быть уверенным, что вы получите все такие зависимости.
Веб-страница обходчика зависимостей называет эти скрытые зависимости явными (динамическими или динамическими) и системными перехватчиками (внедренными зависимостями). Смотрите ссылку выше для более подробной информации.
Heat.exe Извлечение
После того, как вы определили, какие файлы отсутствуют для работы извлечения WiX heat.exe, вы можете поместить эти файлы "рядом" с вашей COM-библиотекой, чтобы они находились во время ее загрузки. Вы можете протестировать запуск с помощью regsvr32.exe, чтобы увидеть, если регистрация завершена правильно. Там не должно быть никаких сообщений об ошибках, когда вы запускаете регистрацию вручную, как это. Не забудьте запустить регистрацию из командной строки с повышенными правами.
Несколько других ответов от stackru объясняют, как использовать heat.exe - я давно его не использовал: как запустить heat.exe и зарегистрировать dll в wix. Вот официальная документация для heat.exe от самих ребят из WiX. Это может быть несколько пугающий инструмент - у него много функций.
В простейшей форме (для обычных 32-битных COM-файлов со всеми зависимостями, доступными в пути или локальной папке) вы можете запустить эту командную строку heat.exe, чтобы сгенерировать выходной исходный файл WiX с именем YourFileName.wxs
со всеми необходимыми данными реестра COM.
heat.exe file YourFileName.ocx -o YourFileName.wxs
Несколько лет назад я написал ответ, показывающий, как включить экспортированные данные реестра WiX в ваш основной источник WiX: Как ссылаться на тепловую мощность (wxs) в Wix (командная строка). Я считаю, что это точное описание процедуры, но по какой-то причине кто-то отказался от ответа. Пожалуйста, попробуйте и посмотрите, работает ли он для вас.
Важный!: heat.exe еще не правильно обрабатывает 64-разрядные двоичные файлы COM (декабрь 2017 г.).
Мне сообщили, что пакет расширения WiX (не бесплатный) поддерживает 64-разрядные двоичные файлы и предоставляет ряд других функций. Я полагаю, что могу ссылаться на него (я не связан с FireGiant): https://www.firegiant.com/wix/wep-documentation/harvesting/. Каким-то образом люди должны знать об этих вещах, но я не уверен насчет этикета стекового потока.
Ваши двоичные файлы 64-битные? (это не выглядит так из вашей установочной папки, но я добавляю это для тех, кто может его найти). Что касается 64-битного компонента, я думаю, что мы прошли полный круг и должны посоветовать вам либо использовать вышеупомянутую функцию пакета расширения, либо просто попытаться настроить саморегистрацию файла, как описано здесь. Я ненавижу это "решение" для самостоятельной регистрации, но я не могу думать ни о каких других быстрых исправлениях в данный момент (ни одно, которое я бы порекомендовал в любом случае). Я проверю снова. Обязательно проверьте последнюю версию WiX, чтобы увидеть, была ли исправлена 64-битная проблема, прежде чем приступать к этой "саморегистрации". По крайней мере, это лучше, чем пытаться зарегистрироваться с помощью пользовательских действий и пакетных файлов (что никогда не следует делать - существует так много потенциальных проблем, связанных со сложным упорядочением пользовательских действий MSI, олицетворением / возвышением, подготовкой, режимами установки с тихим и интерактивным упомянуть о возможных помехах со стороны программного обеспечения безопасности, и этот список можно продолжить).
Некоторые ссылки:
Просто добавьте еще один ответ с информацией о том, как эффективно использовать procmon.exe для отладки отсутствующих зависимостей при самостоятельной регистрации с использованием regsvr32.exe
,
По сути, вы должны установить фильтр включения для того, какие события вы хотите отслеживать и записывать, в противном случае вы получите всемогущий список не относящихся к делу событий, и в море бесполезной информации трудно найти то, что вам нужно:
- Чтобы ограничить полученную информацию о процессе тем, что вам нужно, просто перейдите на
Filter => Filter...
- Установите левый выпадающий
Process Name
а затем второй столбецis
и, наконец, введитеregsvr32.exe
в правом поле, как показано на рисунке выше. - Крайне важно установить самую правую коробку в
Include
, Затем нажмите ОК. - Все ненужные события должны теперь подавляться и только
regsvr32.exe
события отображаются (когда вы запускаете его). - Бежать
regsvr32.exe
нормальный путь и ищитеNAME NOT FOUND
"записи (или аналогичные) в списке. - На рисунке ниже
MMUtilities.dll
не может быть найден. Другими словами, это недостающая зависимость.
Другой способ отладки отсутствующих зависимостей во время саморегистрации - использовать Dependency Walker, как показано в моем другом ответе в этой "теме" или в вопросе, или как его там называть. Обычно я считаю Dependency Walker более быстрым вариантом, но ProcMon, возможно, лучше в целом - если вы не отлаживаете EXE-файл, то Dependency Walker имеет превосходное качество. Profile
особенность (Profile => Start Profiling...
).
Идея не в том, чтобы использовать bat-файл для регистрации dll. Пусть установщик Windows /WiX сделает это за вас. На это уже отвечали в прошлом и здесь.