Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2011.08.21;
Скачать: [xml.tar.bz2];

Вниз

Получение текста ошибки при вызове LoadLibrary в сервисе   Найти похожие ветки 

 
Гость   (2009-08-07 14:44) [0]

Здравствуйте.

Для саморазвития заинтересовался такой проблемой.
Есть dll (libpq.dll), которая требует другие библиотеки (commerr32.dll).
Если commerr32.dll отсутствует, то при вызове LoadLibrary("libpq.dll") появится messagebox:


---------------------------
Form1: testDatabases.exe - Не удалось найти компонент
---------------------------
Приложению не удалось запуститься, поскольку comerr32.dll не был найден. Повторная установка приложения может исправить эту проблему.
---------------------------
ОК  
---------------------------


В GUI приложении все хорошо, и пользователю понятно чего не хватает. Но в сервисе сообщения не будет, а хотелось бы его вывести в лог. В общем интересуют вопросы:
1. Как подавить это сообщение?
2. Как получить его текст?

Подавить сообщение получилось так:
 
SetErrorMode(SEM_FAILCRITICALERRORS);
hDll := LoadLibrary("libpq.dll");


А вот текст подавленного сообщения как получить - не понятно.


 
Palladin ©   (2009-08-07 14:49) [1]

Function vtSysErrorString(p_nLastErrorValue:Integer):String;
Begin
SetLength(Result,10*1024);
SetLength(Result,FormatMessage(
 FORMAT_MESSAGE_FROM_SYSTEM,
 Nil,
 p_nLastErrorValue,
 0,
 @Result[1],
 10*1024,
 Nil
));
End;


 
Гость   (2009-08-07 15:04) [2]


> Palladin ©   (07.08.09 14:49) [1]

Нет, ты не правильно понял.

После вызова

hDll := LoadLibrary("libpq.dll");

if hDll = 0 then
 raise Exception.Create(SysErrorMessage(GetLastError));


Будет два сообщения:
В момент вызова LoadLibrary:
Приложению не удалось запуститься, поскольку comerr32.dll не был найден. Повторная установка приложения может исправить эту проблему.
И при получении GetLastError
Не найден указанный модуль.

Но в сервисе первую ошибку мы не увидим, только вторую, из которой вообше непонятно чего не хватает.


 
Palladin ©   (2009-08-07 15:26) [3]

Try
Except
on e:Exception do WriteLog(e.Message);
End;

или я еще чего то не понял?


 
Сергей М. ©   (2009-08-07 15:41) [4]


> Palladin ©   (07.08.09 15:26) [3]


Он имеет ввиду, что в сообщении дельфийского исключения нет детальной инф-ции о конкретном отсутствующем модуле.


 
Медвежонок Пятачок ©   (2009-08-07 16:34) [5]

Будет два сообщения:
В момент вызова LoadLibrary:
Приложению не удалось запуститься, поскольку comerr32.dll не был найден. Повторная установка приложения может исправить эту проблему.


Ни одного не будет.

А либа у него не грузится потому что текущий каталог процесса сервиса это windows\system32, а не каталог где лежит exe сервиса


 
Гость   (2009-08-07 19:30) [6]


> Palladin ©   (07.08.09 15:26) [3]

LoadLibrary не генерирует исключения

Из MSDN:
Remarks

To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function.


Сообщение которое выскакивает при невозможности загрузки библиотеки можно погасить, если вызвать перед LoadLibrary
SetErrorMode(SEM_FAILCRITICALERRORS);

см. SafeLoadLibrary из SysUtils

Но как получить его текст мне не понятно. Возможно есть какой-то механизм, чтобы Windows вызывала CallBack функцию при возникновении таких ошибок..


 
Гость   (2009-08-07 19:32) [7]


> Медвежонок Пятачок ©   (07.08.09 16:34) [5]

У меня все загружается нормально, я искуственно создал такую ситуацию, и мне нужно чтобы в евентлоге был понятный текст ошибки, а не тот что можно получить с помощью GetLastError


 
Медвежонок Пятачок ©   (2009-08-07 20:11) [8]

ожидаемый понятный текст ошибки был не от лоадлайбрари, а от того, что загружаемая либа статически импортирует функции из дгругих либ


 
Leonid Troyanovsky ©   (2009-08-10 14:13) [9]


> Гость   (07.08.09 19:32) [7]

> У меня все загружается нормально, я искуственно создал такую
> ситуацию, и мне нужно чтобы в евентлоге был понятный текст
> ошибки, а не тот что можно получить с помощью GetLastError

По коду ошибки можно получить ее описание хоть по
Numerical List of Error Codes, т.е. писать это в лог нет обязательно.

Узнать больше подробностей можно так:

function SysErrorMessageEx(ErrorCode: Longint): string;
var
 Len: Integer;
 Buffer: array [0..4095] of Char;
begin
 Len := FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM or
                       FORMAT_MESSAGE_IGNORE_INSERTS,
                       nil,
                       ErrorCode,
                       0,
                       Buffer,
                       SizeOf(Buffer),
                       nil);
 SetString(Result, Buffer, Len);
 if (Len = 0) then
   Result := Format(rserrfmtmsgerr, [SysErrorMessage(GetLastError)]);
 Result := Format(rserrfmtmsg, [ErrorCode, Result]);
end;

Но, для подстановки в текст возможных параметров  (до 4, AFAIK)
потребуется гораздо больше усилий. Поэтому проще, IMHO,
писать в лог все те значения, которые будут полезны для
анализа причины катастрофы.
Например:

var
 hdll: THandle;
 oldmode: UINT;
 fname: String;
 ..
 oldmode := SetErrorMode(SEM_FAILCRITICALERRORS);
 fname := ..;
 hdll := LoadLibrary(PChar(fname));
 if (hdll = 0) then
   WriteMessageToLog( Format("Loading library %s error: %s",
                              [fname, SysErrorMessageEx(GetLastError)]));
 SetErrorMode(oldmode);
 ..


 
Leonid Troyanovsky ©   (2009-08-10 14:20) [10]


> Leonid Troyanovsky ©   (10.08.09 14:13) [9]

> function SysErrorMessageEx(ErrorCode: Longint): string;

Поправлюсь:
resourcestring
 rserrfmtmsg = "Code: %d. Message: %s";
 rserrfmtmsgerr = "Formating message error! %s";

function SysErrorMessageEx(ErrorCode: Longint): string;
var
 Len: Integer;
 Buffer: array [0..4095] of Char;
begin
 Len := FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM or
                       FORMAT_MESSAGE_IGNORE_INSERTS,
                       nil,
                       ErrorCode,
                       0,
                       Buffer,
                       SizeOf(Buffer),
                       nil);

 if (Len = 0) then
   Result := Format(rserrfmtmsgerr, [SysErrorMessage(GetLastError)]);
 else
   SetString(Result, Buffer, Len);
 Result := Format(rserrfmtmsg, [ErrorCode, Result]);
end;

sorry.

--
Regards, LVT.


 
Гость   (2009-08-10 19:24) [11]


> Медвежонок Пятачок ©   (07.08.09 20:11) [8]
>
> ожидаемый понятный текст ошибки был не от лоадлайбрари,
> а от того, что загружаемая либа статически импортирует функции
> из дгругих либ

Да, я понимаю это. Вариант предложенный Leonid Troyanovsky тоже на дает информации какой именно модуль загрузить не удалось.

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



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2011.08.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.004 c
13-1126851536
Антон773
2005-09-16 10:18
2011.08.21
перенос кода с win32 на .net


2-1305111938
leonid666
2011-05-11 15:05
2011.08.21
ole-container немогу открыть ворд


3-1262954585
serko
2010-01-08 15:43
2011.08.21
Обработка ошибок


15-1304569666
OW
2011-05-05 08:27
2011.08.21
Indy. IdSMTP. Lotus Notes 6.5 Incorrect format in MIME data


15-1304314820
erutan
2011-05-02 09:40
2011.08.21
ошибка при загрузке Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский