我用上面的方法不能成功:
修改后以下,但不支持附件
unit SimpleMails;
interface
uses
Windows, Messages, SysUtils, Classes, Winsock, Psock;
type
TSimpleSMTP = class(TPowerSock)
private
FBody: string;
FPassword: string;
FSubject: string;
FUsername: string;
FMailFrom: string;
FMailTo: string;
procedure SetBody(const Value: string);
procedure SetMailFrom(const Value: string);
procedure SetMailTo(const Value: string);
procedure SetPassword(const Value: string);
procedure SetSubject(const Value: string);
procedure SetUsername(const Value: string);
procedure RaiseError(const Msg: string);
published
property MailTo: string read FMailTo write SetMailTo;
property MailFrom: string read FMailFrom write SetMailFrom;
property Subject: string read FSubject write SetSubject;
property Body: string read FBody write SetBody;
property Username: string read FUsername write SetUsername;
property Password: string read FPassword write SetPassword;
public
function Transaction(const CommandString: String): String; override;
public
function SendMail: Boolean;
constructor Create(AOwner: TComponent); override;
end;
function EncodeBase64(Source: string): string;
procedure Register;
implementation
const
BaseTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function EncodeBase64(Source:string):string;
var
Times, LenSrc, i: Integer;
x1, x2, x3, x4: Char;
xt: Byte;
begin
Result := '';
LenSrc := Length(Source);
if LenSrc mod 3 = 0 then
Times := LenSrc div 3
else
Times := LenSrc div 3 + 1;
for i := 0 to Times - 1 do
begin
if LenSrc >= (3 + i * 3) then
begin
x1 := BaseTable[(ord(Source[1 + i * 3]) shr 2)+1];
xt := (ord(Source[1 + i * 3]) shl 4) and 48;
xt := xt or (ord(Source[2 + i * 3]) shr 4);
x2 := BaseTable[xt + 1];
xt := (Ord(Source[2 + i * 3]) shl 2) and 60;
xt := xt or (Ord(Source[3 + i * 3]) shr 6);
x3 := BaseTable[xt + 1];
xt := (ord(Source[3 + i * 3]) and 63);
x4 := BaseTable[xt + 1];
end
else if LenSrc >= (2 + i * 3) then
begin
x1 := BaseTable[(Ord(Source[1 + i * 3]) shr 2) + 1];
xt := (Ord(Source[1 + i * 3]) shl 4) and 48;
xt := xt or (Ord(Source[2 + i * 3]) shr 4);
x2 := BaseTable[xt + 1];
xt := (Ord(Source[2 + i * 3]) shl 2) and 60;
x3 := BaseTable[xt + 1];
x4 := '=';
end else
begin
x1 := BaseTable[(Ord(Source[1 + i * 3]) shr 2)+1];
xt := (Ord(Source[1 + i * 3]) shl 4) and 48;
x2 := BaseTable[xt + 1];
x3 := '=';
x4 := '=';
end;
Result := Result + x1 + x2 + x3 + x4;
end;
end;
// this function by Matjaz Bravc
function sak_GetInternetDate( const Date: TDateTime):string;
(* The date in RFC 822 conform string format *)
function int2str(value:integer; len:byte):string;
begin
result := IntToStr( value);
while length( result) < len do result := '0' + result;
end;
function GetTimeZoneBias:longint;
(* The offset to UTC/GMT in minutes of the local time zone *)
var tz_info: TTimeZoneInformation;
begin
case GetTimeZoneInformation(tz_info) of
1: result := tz_info.StandardBias+tz_info.Bias;
2: result := tz_info.DaylightBias+tz_info.Bias;
else
result := tz_info.DaylightBias+tz_info.Bias;
end;
end;
function GetTimeZone:string;
var bias: longint;
begin
bias := GetTimeZoneBias;
if bias = 0 then
begin
result := 'GMT';
end else
begin
if bias < 0 then
begin
result := '+' + int2str(abs(bias) div 60,2)+int2str(abs(bias) mod 60,2);
end else
begin
if bias > 0 then
begin
result := '-' + int2str(bias div 60,2)+int2str(bias mod 60,2);
end;
end;
end;
end;
var
d, m, y, w, h, mm, s, ms: word;
const
WeekDays: array [1..7] of string[3] = ('Sun','Mon','Tue','Wed',
'Thu','Fri','Sat');
Months: array [1..12] of string[3] = ('Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec');
begin
DecodeDate( date, y, m, d);
DecodeTime( date, h, mm, s, ms);
w := DayOfWeek( date);
Result := weekdays[w] + ', ' +
inttostr(d) + ' ' +
months[m] + ' ' +
inttostr
+ ' ' +
int2str(h,2) + ':' +
int2str(mm,2) + ':' +
int2str(s,2) + ' ' +
GetTimeZone;
end;
function GetComputerName: string;
var
n: Cardinal;
begin
n:= MAX_COMPUTERNAME_LENGTH + 1;
SetLength(Result, n);
Windows.GetComputerName(PChar(Result), n);
SetLength(Result, n);
end;
{ TSimpleSMTP }
constructor TSimpleSMTP.Create(AOwner: TComponent);
begin
inherited;
Port:= 25;
end;
procedure TSimpleSMTP.SetBody(const Value: string);
begin
FBody := Value;
end;
procedure TSimpleSMTP.SetMailFrom(const Value: string);
begin
FMailFrom := Value;
end;
procedure TSimpleSMTP.SetMailTo(const Value: string);
begin
FMailTo := Value;
end;
procedure TSimpleSMTP.SetPassword(const Value: string);
begin
FPassword := Value;
end;
procedure TSimpleSMTP.SetSubject(const Value: string);
begin
FSubject := Value;
end;
procedure TSimpleSMTP.SetUsername(const Value: string);
begin
FUsername := Value;
end;
function TSimpleSMTP.Transaction(const CommandString: String): String;
var
S: string;
begin
Result:= inherited Transaction(CommandString);
S:= Result;
while Copy(S, 4, 1) = '-' do
begin
S:= Readln;
Result:= Result + S;
end;
end;
procedure TSimpleSMTP.RaiseError(const Msg: string);
begin
Raise Exception.Create(Msg);
end;
function TSimpleSMTP.SendMail: Boolean;
var
i: integer;
List: TStringList;
Header: string;
begin
Result:= False;
if not Connected then RaiseError(Host + ' not connect');
// read welcome ...
Header:= Readln;
while Copy(Header, 4, 1) = '-' do Header:= Self.Readln;
// say hello
Transaction('EHLO ' + GetComputerName);
// smtp server login
Transaction('AUTH LOGIN');
if ReplyNumber = 334 then
begin
Transaction(EncodeBase64(FUsername));
Transaction(EncodeBase64(FPassword));
if ReplyNumber>400 then RaiseError(TransactionReply);
end;
// mail from
Transaction(Format('MAIL FROM:<%s>', [FMailFrom]));
if ReplyNumber>400 then RaiseError(TransactionReply);
// send
List:= TStringList.Create;
List.Text:= StringReplace(FMailTo, ';', #13#10, [rfReplaceAll]);
for i:=0 to List.Count-1 do
begin
if List
<>'' then
Transaction(Format('RCPT TO:<%s>', [List]));
end;
Transaction('DATA');
if ReplyNumber<>354 then RaiseError(TransactionReply);
Header:= Format(
'Date: %s'#13#10 +
'From: %s<%s>'#13#10 +
'Subject: %s'#13#10 +
'To: %s'#13#10#13#10,
[sak_GetInternetDate(now), FUserName, FMailFrom, FSubject, FMailTo]);
Transaction(Header + Body + #13#10'.'#13#10#13#10);
if ReplyNumber>400 then RaiseError(TransactionReply)
else Result:= True;
Transaction('QUIT')
end;
procedure Register;
begin
RegisterComponents('FastNet', [TSimpleSMTP]);
end;
end.