Скрипты Windows: возможно ли зафиксировать ошибки отсутствующей DLL в файле журнала? - PullRequest
0 голосов
/ 11 декабря 2019

Когда вы пытаетесь запустить программу в Windows, и загрузчик не может найти все необходимые библиотеки DLL, поведение по умолчанию - это всплывающее диалоговое окно, описывающее проблему, включая как имя программы, так иимя (одного из) отсутствующих DLL. Затем процесс зависает, пока кто-нибудь не нажмет OK, а затем завершится с кодом ошибки. Вот пример этого диалогового окна:

Example of the dialog box that Windows shows by default when a required DLL is not available. The dialog box title reads

Теперь предположим, что вы пишете какой-то автоматизированный процесс, который может дать сбой по этой причине, например, запуск тестов CI послеустановка, где частью является обеспечение того, чтобы установщик установил все библиотеки DLL. Вы не хотите, чтобы ваши сборщики зависали, ожидая, пока кто-нибудь нажмет на диалоговое окно, отображаемое на мониторе, которого у компьютера физически нет, потому что он где-то находится в стойке сервера. Вы хотите, чтобы цикл тестирования немедленно прекратился, а детали были записаны в журнал.

Ваш драйвер сборки может отключить это диалоговое окно для себя и всех своих дочерних процессов (при условии, что никто не использует CREATE_DEFAULT_ERROR_MODE), вызвав SetErrorMode:

SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
hProc = CreateProcess(...);

Однако это решает только половину проблемы. Процесс, вызывающий ошибку, будет завершен с состоянием выхода 0xC0000135 (STATUS_DLL_NOT_FOUND), но ни имя исполняемого файла проблемы, ни имя отсутствующей DLL не сообщаются нигде, и я не могу его найти.

Итаквот актуальный вопрос: как из кода, выполняемого в драйвере сборки, получить имя исполняемого файла проблемы и имя отсутствующей DLL, чтобы я мог записать их в журналы сборки CI? Все идет, , за исключением , что код самого исполняемого файла проблемы и его DLL не может быть изменен (поскольку это должно быть общим решением), и настоятельно рекомендуется подход, который не требует повышенных привилегий.

(Это дополнительный вопрос для Подавить сообщение об ошибке «Программа не запускается из-за отсутствия X.dll», всплывающее сообщение об ошибке . Я смутно намеревался написать его уже много лет. )

1 Ответ

0 голосов
/ 11 декабря 2019

Несмотря на то, что это немного излишне, вы можете написать программу / скрипт, который анализирует формат PE каждого исполняемого файла, просматривает таблицу импорта, чтобы перечислить импортированные модули, и проверяет, существует ли каждый модуль в системе (т.е. в \Windows\System32, текущем каталоге и т. д.).

Затем, если в рассматриваемом исполняемом файле отсутствует импорт, зарегистрируйте исполняемый файл и отсутствующий импорт где-нибудь (и, конечно, не запускайте исполняемый файл).

Если вы хотите сделать это в Python, модуль pefile превосходен (https://pypi.org/project/pefile/).

(Обновление: это не будет работать для библиотек DLL, которые импортируются через LoadLibrary)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...