我们使用 Indy,我们需要在我们的应用程序中支持 SSL 电子邮件,但是我们需要将我们的应用程序放在一个 .Exe 中。
我们知道默认的 Indy 处理程序需要在路径中包含 dll。从 EXE 的一个资源中提取 Dll 将是最后的手段。
有更好的想法吗?
试试SSLBlackBox。
TOndrey 给了你一个很好的答案。我也使用 SecureBlackBox。您可以考虑其他一些第三方组件:
请注意:如果您在可执行文件中添加 SSL/TLS 支持,它可能会受到 export 的限制。如果您在美国,这可能意味着您的申请不能出售或提供给美国以外的人。这就是为什么这些 DLL 本身不是 Indy 或 Delphi 的一部分。
Delphi 使用的库实际上是从OpenSSL项目编译的 DLL。但是,如果您对 C 有很好的了解,那么您应该能够将源代码编译为 .obj 文件并将它们与您的 Delphi 代码链接。您可能还需要为此修改部分 Indy 代码。当然,其他人也可以这样做,但是由于这些出口限制,这使得那些 Indy 组件(甚至是 Delphi 本身)的出口更加复杂。
有趣的是,源代码受到第一修正案的保护,基本上允许您将代码打印在一本书中,然后将其发送给某个流氓国家。虽然如果你以数字形式发送它(无论是否编译),那么你就犯了联邦罪行,并且在淋浴时拿起肥皂至少一年可能必须小心......没有人声称法律是有道理的。他们可能只是[哔]的痛苦......
其他 SSL 解决方案不能与 Indy 组件一起使用,这意味着您必须重写部分代码以支持其他解决方案。
“单个 EXE”要求是出于分发目的,还是在客户端计算机上运行时也必须是单个 .EXE 文件?
如果仅用于分发目的,您可以将 DLL 文件附加到 .EXE 文件的末尾,然后 - 当程序启动时 - 从 .EXE 文件中提取它们并将它们作为 .DLL 文件存储在本地,如下所示:
VAR F,O : FILE;
VAR BUF : ARRAY[1..<MaxSizeOfDLLs>] OF BYTE;
ASSIGN(F,ParamStr(0)); RESET(F,1);
SEEK(F,<OriginalExeSize>);
BLOCKREAD(F,BUF,<FirstDllSize>);
ASSIGN(O,<NameOfFirstDLL>); REWRITE(O,1);
BLOCKWRITE(O,BUF,<FirstDllSize>); CLOSE(O);
BLOCKREAD(F,BUF,<SecondDllSize>);
ASSIGN(O,<NameOfSecondDLL>); REWRITE(O,1);
BLOCKWRITE(O,BUF,<SecondDllSize>); CLOSE(O);
SEEK(F,<OriginalExeSize>); TRUNCATE(F); CLOSE(F)
Quick'n'Dirty,格式不正确等,但应该给你基本的想法。
您是否尝试过自己编译 OpenSLL 源并将目标文件导入 Delphi?
推荐阅读:在 Delphi 中使用 C 对象文件- 解释如何创建不需要 DLL 并且可以一体部署的程序
我将 Microsoft 的 CAPICOM 用于 SSl3,它解决了我的需求……它可以自由再分发,但已停产
如果您尝试其他组件,也许您应该查看 SYNAPSE(位于http://synapse.ararat.cz/)(我也使用)它可以与 StreamSec(和其他)一起通过 ssl 发送电子邮件。它免费且易于工作。
可以将这些 DLL 作为资源包含到程序的可执行文件中,并在使用时将它们导出到文件中,甚至可以通过重新定位代码并在内存中搜索入口点来使用它们而不先导出它们。我在某处有代码可以做后者....
Const
cdoSendUsingMethod = 'http://schemas.microsoft.com/cdo/configuration/sendusing';
cdoSMTPServer = 'http://schemas.microsoft.com/cdo/configuration/smtpserver';
cdoSMTPServerPort = 'http://schemas.microsoft.com/cdo/configuration/smtpserverport';
cdoSendServerPort = '25';
cdoSendUsingPort = 2;
cdoSMTPConnectionTimeout = 'http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout';
cdoSMTPAuthenticate = 'http://schemas.microsoft.com/cdo/configuration/smtpauthenticate';
cdoAnonymous = '0';
cdoBasic = '1';
cdoSMTPUseSSL = 'http://schemas.microsoft.com/cdo/configuration/smtpusessl';
cdoSendUserName = 'http://schemas.microsoft.com/cdo/configuration/sendusername';
cdoSendPassword = 'http://schemas.microsoft.com/cdo/configuration/sendpassword';
cdoURLGetLatestVersion = 'http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion';
...
function SensCDOMail (ASubject, AFrom, ATo, ABody, ASmtpServer : WideString): String;
var
cdoMessage:OleVariant;
cdoConfiguration: OleVariant;
begin
//Configuration Object
cdoMessage:= CreateOleObject('CDO.Message');
cdoConfiguration:= CreateOleObject('CDO.Configuration');
try
cdoConfiguration.Fields(cdoSendUsingMethod):= cdoSendUsingPort;
cdoConfiguration.Fields(cdoSMTPServer):= ASmtpServer;
cdoConfiguration.Fields(cdoSMTPServerPort):= cdoSendServerPort;
cdoConfiguration.Fields(cdoSMTPAuthenticate):= cdoAnonymous;
cdoConfiguration.Fields(cdoSMTPUseSSL ):= True; // use SSL
cdoConfiguration.Fields.Update;
cdoMessage.Configuration:= cdoConfiguration;
cdoMessage.To := ATo;
cdoMessage.From := AFrom;
cdoMessage.Subject := ASubject;
//cdoMessage.HTMLBody := ABody; //Want to send in Html format
cdoMessage.TextBody := ABody; //Want to send in text format
cdoMessage.Send;
finally
VarClear(cdoMessage);
VarClear(cdoConfiguration);
end;
end;