Catch MSVCR120 отсутствует сообщение об ошибке в Delphi
Я написал автоматический клиент загрузки HTTPS, который не должен требовать взаимодействия с пользователем.
Все было безупречно, пока я не развернул его вслепую на удаленной системе, к которой у меня нет доступа к удаленному рабочему столу. Инструмент сообщил в журналах, что отсутствуют библиотеки SSL.
Ок я развернул LIBEAY32.dll
а также SSLEAY32.dll
в папку приложения на удаленной системе, но затем инструмент завис, и я не мог понять, что происходит, пока я не написал инструмент, который делает удаленный снимок экрана.
На скриншоте я вижу модальное окно из csrss.exe
обработать с сообщением:
Программа не может запуститься, потому что MSVCR120.dll отсутствует на вашем компьютере.
Окно появилось несмотря на то, что try except
блоки и Application.OnException
обработчик.
Мне бы хотелось, чтобы в таких случаях приложение не задерживалось, чтобы оно могло сообщать о сбое в свой журнал.
Как этого добиться?
В текущей реализации TIdHttp.Post
звонок просто зависает.
PS Я решил проблему отсутствия DLL, скопировав ее в папку приложения, но у меня вопрос о том, чтобы отловить такие ошибки.
2 ответа
Чтобы избежать этой ошибки, вы можете использовать библиотеки OpenSSL, доступные по https://indy.fulgan.com/SSL/
У них нет этой зависимости от MSVCRT.
Или используйте TNetHTTPClient.
Из этого ответа:
TNetHTTPClient был представлен в Delphi XE8.
Наиболее важным преимуществом TNetHTTPClient является то, что оно позволяет вашему приложению поддерживать HTTPS без необходимости обеспечивать собственную поддержку SSL/TLS. TNetHTTPClient опирается на поддержку SSL / TLS, предоставляемую операционной системой.
Используя информацию из комментария Реми Лебо, я экспериментировал с SetErrorMode
функция в Delphi 6.
Установка состоит из трех проектов:
- Хост-приложение, которое динамически связывает вызывающую DLL,
- вызывающая DLL, которая статически связывает рабочую DLL,
- и рабочая DLL.
Сначала я помещаю обе библиотеки DLL в папку приложения хоста, проверяю, что все работает, а затем удаляю рабочую библиотеку DLL и тестирую ее без нее.
Вот некоторый код:
Хост-приложение
program MyHost;
uses
Windows, SysUtils;
var
hLib: HMODULE;
procedure Box(msg: WideString);
begin
MessageBoxW(0, PWideChar(msg), 'MyHost Message', 0);
end;
procedure ShowLastError();
begin
Box('LastError: ' + SysErrorMessage(GetLastError()));
end;
type
TDoWork = procedure();
var
DoWork: TDoWork;
begin
SetErrorMode(SEM_FAILCRITICALERRORS);
try
{Without SetErrorMode it displays modal dialog.
No exception is generated.
After clicking at [Ok], it goes to "if hLib = 0".
With SetErrorMode it just goes to "if hLib = 0"}
hLib := LoadLibrary('CallerLib.dll');
if hLib = 0 then begin
ShowLastError();
Halt(1);
end;
try
@DoWork := GetProcAddress(hLib, 'DoWork');
if @DoWork <> nil then DoWork();
finally
FreeLibrary(hLib);
end;
except
on ex: Exception do Box(ex.ClassName + ': ' + ex.Message);
end;
end.
Caller DLL
library CallerLib;
uses
Windows;
//Static linking
procedure Function1(); stdcall; external 'MyLib.dll';
procedure Function2(); stdcall; external 'MyLib.dll';
//To be dynamically linked
procedure DoWork(); stdcall; export;
begin
Function1();
Function2();
end;
exports
DoWork;
end.
Рабочая DLL
library MyLib;
uses
Windows;
procedure Function1(); stdcall; export;
begin
MessageBox(0, 'MyDLL.Function1', 'MyDLL', 0);
end;
procedure Function2(); stdcall; export;
begin
MessageBox(0, 'MyDLL.Function2', 'MyDLL', 0);
end;
exports
Function1, Function2;
end.