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.
Другие вопросы по тегам