Can't load package C:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogExpert250.bpl. Access is denied.Причём клиент утверждал, что файл существует, доступ к нему есть, переустановка EurekaLog не помогает.
Дополнительно было установлено, что код из пакета
EurekaLogExpert250.bpl действительно не получает управления (не выполняется).IDE использует ту же функцию
LoadPackage из модуля SysUtils, что и вы (ваш код). Никакого секретного кода IDE не выполняет. Функция LoadPackage реализована следующим образом:
function LoadPackage(const Name: string; AValidatePackage: TValidatePackageProc): HMODULE;
begin
Result := SafeLoadLibrary(Name);
if Result = 0 then
raise EPackageError.CreateResFmt(@sErrorLoadingPackage, [Name, SysErrorMessage(GetLastError)]); // -----
try
InitializePackage(Result, AValidatePackage);
except
FreeLibrary(Result);
raise;
end;
end;
где функция InitializePackage реализована так:
procedure InitializePackage(Module: HMODULE; AValidatePackage: TValidatePackageProc);
type
TPackageLoad = procedure;
var
PackageLoad: TPackageLoad;
begin
CheckForDuplicateUnits(Module, AValidatePackage);
@PackageLoad := GetProcAddress(Module, 'Initialize'); //Do not localize
if Assigned(PackageLoad) then
PackageLoad
else
raise EPackageError.CreateFmt(sInvalidPackageFile, [GetModuleName(Module)]);
end;
Как вы можете видеть: единственным местом, где при загрузке пакета может возбуждаться исключение с кодом ошибки от ОС (5 = ERROR_ACCESS_DENIED) является помеченная строка. Откуда следует, что ошибка Access Denied при загрузке пакета может произойти только при неудачном вызове функции LoadLibrary.Поэтому клиенту было предложено создать новое пустое VCL приложение с таким тестовым кодом:
procedure TForm1.Button1Click(Sender: TObject);
var
Lib: HMODULE;
begin
Lib := LoadPackage('C:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogExpert250.bpl');
if Lib = 0 then
RaiseLastOSError
else
MessageBox(0, 'The package was loaded!', 'Test', 0);
end;
Как оказалось, тестовое приложение успешно загружает пакет.Чтобы точно быть уверенным, что IDE не выполняет никакого дополнительного скрытого кода, мы попросили клиента создать новые Design-Time пакет с модулем, содержащим только тестовый код:
unit Unit1;
procedure Register;
implementation
uses
Windows, SysUtils;
procedure Register;
var
Lib: HMODULE;
begin
Lib := LoadPackage('C:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogExpert250.bpl');
if Lib = 0 then
RaiseLastOSError
else
MessageBox(0, 'The package was loaded!', 'Test', 0);
end;
end.
И при попытке загрузить этот тестовый модуль IDE снова выдала сообщение об ошибке.Сделаем промежуточный итог:
- Тестовое приложение успешно загружает пакет;
- Тестовый пакет (и IDE) не могут загрузить пакет.
Мы также попытались сделать следующее:Поскольку и мы, и клиент уже по сто раз проверили права доступа к файлуДанный алгоритм не дал никакой новой информации: в отладчике мы увидели, что в отлаживаемом процессе функция
- Запустить IDE (без EurekaLog);
- Открыть пункт меню Run / Load Process;
- Указать
bds.exeкак целевой процесс для отладки;- Запустить второй экземпляр IDE. При этом первый экземпляр будет отладчиком, а второй - отлаживаемым;
- В отлаживаемом процессе попытаться добавить пакет
EurekaLogExpert250.bpl;- В отладчике следить за возникающими исключениями.
LoadLibraryвозвращает 0, что и приводит к возбуждению ошибки - как мы и предполагали выше.
EurekaLogExpert250.bpl и не увидели проблем, нужно было делать что-то ещё.Пакет
EurekaLogExpert250.bpl является Design-Time пакетом. Он зависит от Run-Time пакета EurekaLogCore250.bpl. Это означает, что если функция LoadLibrary загружает пакет EurekaLogExpert250.bpl, то она увидит, что пакет EurekaLogExpert250.bpl ссылается на EurekaLogCore250.bpl и попробует загрузить и его. И если проблема возникла при загрузке пакета EurekaLogCore250.bpl - она всплывёт на верхний уровень и будет возвращаена вызывающему функцией LoadLibrary.Поэтому клиент также проверил файл
EurekaLogCore250.bpl (он находится в папке C:\Windows\System32) и не нашёл проблем.Далее мы попросили клиента использовать утилиту Process Monitor от Microsoft / SysInternals, чтобы пронаблюдать за тем, как IDE производит доступ к файлам. Необходимо было запустить IDE, открыть диалог добавления пакета, затем запустить Process Monitor и указать фильтр "Process Name=bds.exe => include". После чего попытаться добавить пакет, увидеть сообщение об ошибке и сохранить полученный отчёт.
В полученном отчёте мы запустили поиск по слову "Eureka" и сразу же увидели, что
bds.exe смогла открыть и прочитать файл EurekaLogExpert250.bpl - что дополнительно подтверждает, что с файлом EurekaLogExpert250.bpl всё в порядке.А вот строчки сразу ниже ввели нас в недоумение: Process Monitor сообщил, что
bds.exe пытается получить доступ к EurekaLogCore250.bpl из папки \bin IDE. Это странно, потому что современные версии EurekaLog не трогают папку \bin IDE.(Очень) старые версии EurekaLog устанавливали файлы ecc32.exe в папкуНо когда мы попытались проверить права доступа к файлу\binIDE. Нам пришлось убрать это поведение, потому что современные версии IDE могут выбросить ошибку проверки целостности/лицензии, если в папке\binбудут находиться сторонние файлы:
Question: I’ve installed and registered C++ Builder or Delphi, yet when it starts I am brought to a web page with the error “Product or License Validation Error”. How can I fix this?Поэтому современные версии EurekaLog не копируют никаких файлов в папку
Answer: By far the most common cause for this error is having files or applications not provided by Embarcadero that are copied into the bin folder below where RAD Studio is installed. Only files provided by Embarcadero may reside in the bin folder.\binIDE.
\bin\EurekaLogCore250.bpl, то... не нашли такого файла!Как оказалось: дело в том, что
\bin\EurekaLogCore250.bpl - это каталог! Тайна раскрыта!Итак, происходило следующее:
- IDE вызывает функцию
LoadPackageдля загрузки пакета; - Функция
LoadPackageвызывает функциюLoadLibraryдля загрузки файлаEurekaLogExpert250.bpl; - Функция
LoadLibrary(успешно) открывает и читает файлEurekaLogExpert250.bpl; - Функция
LoadLibraryвидит, что файлEurekaLogExpert250.bplсодержит ссылку на файлEurekaLogCore250.bpl; - Функция
LoadLibraryпытается загрузить файлEurekaLogCore250.bpl; - Функция
LoadLibraryиспользует стандартные правила поиска библиотек операционной системы и видит, чтоEurekaLogCore250.bplнаходится прямо тут: в папке\binIDE; - Функция
LoadLibraryпытается загрузитьEurekaLogCore250.bplиз папки\binIDE; - Функция
LoadLibraryвозвращает ошибку 5 (Access Denied), поскольку папкаEurekaLogCore250.bplиз папки\binIDE не имеет права доступа "EXECUTE".
И, действительно, всё заработало после удаления папки
EurekaLogCore250.bpl из папки \bin IDE.Но откуда взялась папка
EurekaLogCore250.bpl в папке \bin IDE? Я не знаю. Установщик EurekaLog сделан с помощью InnoSetup. Разумеется, установочный файл InnoSetup для EurekaLog понятия не имеет про установленные у вас IDE и каталоги, в которые они установлены. И поэтому установочный файл InnoSetup для EurekaLog не сможет создать там папку - просто потому, что он не знает, где это.Регистрация же EurekaLog в IDE производится программой регистрации:
.exe файлом, скомпилированным в Delphi из нашего исходного кода. Проблема в том, что в нашем исходном коде для регистрации EurekaLog нет ни одного вызова MkDir или ForceDirectories: программа регистрации EurekaLog не создаёт каталогов, она копирует файлы и вносит данные о них в реестр Windows.Даже если бы
EurekaLogCore250.bpl в папке \bin IDE создавался нашим установщиком: почему это каталог, а не файл? И почему он один? Почему там же нет EurekaLogExpert250.bpl и EurekaLogComponent250.bpl - ведь эти три файла идут вместе.Пока всё выглядит так, словно кто-то создал каталог
EurekaLogCore250.bpl в папке \bin IDE. Возможно, это какой-то IDE эксперт?Если вы наш клиент, если вы увидели эту ошибку и знаете, кто создаёт каталог
EurekaLogCore250.bpl в папке \bin IDE - пожалуйста, сообщите нам.
Комментариев нет :
Отправить комментарий
Можно использовать некоторые HTML-теги, например:
<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>
Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и (опционально) ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.
Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.
Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.
Примечание. Отправлять комментарии могут только участники этого блога.