2

我编写了一个不需要用户交互的无人值守 HTTPS 上传客户端。

在我盲目地将它部署到我没有远程桌面访问权限的远程系统之前,一切都是完美的。该工具在日志中报告 SSL 库丢失。

好的,我部署LIBEAY32.dllSSLEAY32.dll远程系统上的应用程序文件夹,但随后该工具挂起,直到我编写了一个制作远程屏幕截图的工具,我才弄清楚发生了什么。

在屏幕截图中,我看到了一个csrss.exe带有消息的进程模式窗口:

程序无法启动,因为您的计算机缺少 MSVCR120.dll。

尽管有很多try except块和Application.OnException处理程序,窗口还是出现了。

我希望在这种情况下应用程序不会被阻止,因此它可以向日志报告失败。

如何做到这一点?

在当前的实现TIdHttp.Post中,调用只是挂起。

PS我通过将DLL复制到app文件夹来解决DLL的缺失,但我的问题是关于捕获此类错误。

4

2 回答 2

5

为避免此错误,您可以使用https://indy.fulgan.com/SSL/上提供的 OpenSSL DLL

他们对 MSVCRT 没有这种依赖性。

或者,使用TNetHTTPClient

这个答案

TNetHTTPClient 是在 Delphi XE8 中引入的。

TNetHTTPClient 最重要的好处是它允许您的应用程序支持 HTTPS,而无需您自己提供对 SSL/TLS 的支持。TNetHTTPClient 依赖于操作系统提供的 SSL/TLS 支持。

于 2018-10-22T12:43:06.740 回答
1

使用来自 Remy Lebeau 评论的信息,我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.

调用者 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.
于 2018-10-26T22:51:51.660 回答