Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > СРОЧНО!Требуется консультация-почтовые компоненты


Автор: Неизвестный программист 30.3.2005, 15:51
Помогите!Что делать с такой прогой:

Файл sendmail.dpr

Код

program sendmail;

{$APPTYPE CONSOLE}

uses
  Windows, Classes, SysUtils, Registry, IniFiles, IDSmtp, IdMessage, IdEmailAddress;

var

  smtpServer    : string;
  defaultFrom   : string;
  defaultDomain : string;
  messageContent: string;
  errorLogFile  : string;
  authUsername  : string;
  authPassword  : string;

  i    : integer;
  s    : string;
  ss   : TStringStream;
  msg  : TIdMessage;
  f    : TextFile;
  addr : TIdEMailAddressItem;

begin

  // read default domain from registry

  with TRegistry.Create do
  try
    RootKey := HKEY_LOCAL_MACHINE;
    if (OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters')) then
      defaultDomain := ReadString('Domain');
  finally
    Free;
  end;

  // read ini

  with TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini')) do
  try

    smtpServer    := ReadString('sendmail', 'smtp_server',    'mail.mydomain.com');
    defaultDomain := ReadString('sendmail', 'default_domain', defaultDomain);
    defaultFrom   := ReadString('sendmail', 'default_from',   defaultFrom);
    errorLogFile  := ReadString('sendmail', 'error_logfile',  '');
    authUsername  := ReadString('sendmail', 'auth_username',  '');
    authPassword  := ReadString('sendmail', 'auth_password',  '');

    if (smtpServer = 'mail.mydomain.com') or (defaultDomain = 'mydomain.com') then
    begin
      writeln('you must configure the smtp_server and default_domain in ' + fileName);
      halt(1);
    end;

  finally
    Free;
  end;

  if (errorLogFile <> '') and (ExtractFilePath(errorLogFile) = '') then
    errorLogFile := ExtractFilePath(ParamStr(0)) + errorLogFile;

  // read email from stdin

  messageContent := '';
  while (not eof(Input)) do
  begin
    readln(Input, s);
    messageContent := messageContent + s + #13#10;
  end;

  // deliver message

  try

    // load message into stream (TidMessage expects message to end in ".")

    ss  := TStringStream.Create(messageContent + #13#10'.'#13#10);
    msg := nil;

    try

      // load message

      msg := TIdMessage.Create(nil);
      msg.LoadFromStream(ss);

      // check for from and to

      if (Msg.From.Address = '') then
        if (defaultFrom = '') then
          raise Exception.Create('email is missing sender''s address')
        else
          Msg.From.Address := defaultFrom;

      if (Msg.Recipients.Count = 0) then
        if (ParamCount = 0)
          then
            raise Exception.Create('email is missing recipient''s address')
          else
            for i:= 1 to ParamCount do
              begin
                addr := Msg.Recipients.Add;
                addr.Address := ParamStr(i);
              end;



      // add date header if missing

      if (Msg.Headers.Values['date'] = '') then
        Msg.Date := now;

      // append default domain

      if (Pos('@', Msg.From.Address) = 0) then
        Msg.From.Text := Msg.From.Address + '@' + defaultDomain;

      for i := 0 to msg.Recipients.Count - 1 do
        if (pos('@', msg.Recipients[i].Address) = 0) then
          msg.Recipients[i].Address := msg.Recipients[i].Address + '@' + defaultDomain;

      // deliver message

      with TIdSMTP.Create(nil) do
      try
        Host     := smtpServer;
        if (authUsername <> '') then
        begin
          AuthenticationType := atLogin;
          Username := authUsername;
          Password := authPassword;
        end;
        Connect;
        Send(msg);
      finally
        Free;
      end;

    finally
      msg.Free;
      ss.Free;
    end;

  except
    on e:Exception do
    begin
      writeln('sendmail: error during delivery: ' + e.message);

      if (errorLogFile <> '') then
      begin

        AssignFile(f, errorLogFile);
        try

          if (not FileExists(errorLogFile)) then
          begin
            ForceDirectories(ExtractFilePath(errorLogFile));
            Rewrite(f);
          end
          else
            Append(f);

          writeln(f, '[' + DateTimeToStr(Now) + '] ' + e.message);
          closeFile(f);

        except
          on e:Exception do
            writeln('sendmail: error writing to error.log: ' + e.message);
        end;

      end;

      halt(1);
    end;
  end;

end.

У меня Delphi 2005.Открываю этот файл и появляется диалоговое окно:
Upgrading Project: sendmail.dpr
this project must be upgraded before it can be opened.Please select which project type you wish to target
Delphi for .NET
Delphi for Win32

Я отмечаю Delphi for Win32 и нажимаю OK,
Но когда пытаюсь скомпилировать программу или запустить (F9) мне говорят:
[Error] sendmail.dpr(178): E2003 Undeclared identifier: 'AuthenticationType'
[Error] sendmail.dpr(178): E2003 Undeclared identifier: 'atLogin'

Также в Инете я нашел несколько примеров отправки почты с использованием компонентов Indy,но там такая же история:Undeclared identifier: 'AuthenticationType' и все тут!

Прошу писать подробно,так как я с Delphi совсем недавно знаком.
Напоминаю,что программа консольная,то есть без формы.

Автор: Snowy 30.3.2005, 15:58
Под Delphi 7 скомпилилось на ура.
Посмотрел 78-ю строку. Все нормально.
Если на нее ругается, то какие-то проблемы с TIdSMTP.
Может другую версию скачать?
В принципе необходимости в этой строке нет.
Закомментируй ее.

Автор: Неизвестный программист 30.3.2005, 18:50
Цитата(Snowy @ 30.3.2005, 15:58)
Может другую версию скачать?

Я вообще-то диск покупал,а не скачивал.Это что же,мне новую версию Delphi выбрасывать на помойку и взять старую?????
Цитата(Snowy @ 30.3.2005, 15:58)
В принципе необходимости в этой строке нет.
Закомментируй ее.

Разве эта строка не ответственна за авторизацию на SMTP-сервере?
Цитата(Snowy @ 30.3.2005, 15:58)

Если на нее ругается, то какие-то проблемы с TIdSMTP.

А какие могут быть проблемы?Она входит по умолчанию в Delphi и как это узнать?

Автор: <Spawn> 30.3.2005, 19:03
В Delphi 2005 стоит Indy 10(а в D7 Indy 9), если мне не изменяет память. Вот видимо в этом и траблы все, возможно, что свойство как то изменено - проверить нет возможности, т.к. Delphi 2005 слетела (только что запускал - ни один проект создать нельзя, ерроры летятsmile ).

Автор: Неизвестный программист 31.3.2005, 01:15
Цитата
В Delphi 2005 стоит Indy 10(а в D7 Indy 9), если мне не изменяет память. Вот видимо в этом и траблы все, возможно, что свойство как то изменено - проверить нет возможности, т.к. Delphi 2005 слетела (только что запускал - ни один проект создать нельзя, ерроры летятsmile ).

А у тебя несколько версий Delphi стоят?
Я вообще запутался с этим. Как я понял,раньше главным файлом проекта был файл с расширением *.dpr. А в Delphi 2005 - *.bdsproj.
Это что же за такое безобразие - напишешь какую-нибудь полезную прогу, а потом в новой версии тебе скажут гудбай и выкидывай свою прогу на мусорку? Идиотизм полный...

Автор: FRAGNATIC 31.3.2005, 01:18
Цитата
Это что же за такое безобразие - напишешь какую-нибудь полезную прогу, а потом в новой версии тебе скажут гудбай и выкидывай свою прогу на мусорку? Идиотизм полный...

Д2005 не стоит раньше устонавливал) на ней не создовал проекты так что сказать не могу какого раширения они но вот могу сказать с вереностью на 100% что *.dpr проекты она открывает и компилит на ура)

Автор: Неизвестный программист 31.3.2005, 03:40
Цитата(FRAGNATIC @ 31.3.2005, 01:18)
Д2005 не стоит раньше устонавливал) на ней не создовал проекты так что сказать не могу какого раширения они но вот могу сказать с вереностью на 100% что *.dpr проекты она открывает и компилит на ура)

Ну да!Я уже понял.При открытии файла .dpr Delphi 2005 добавляет в папку с исходниками файл проекта с другим расширением - bdsproj.И сколько я находил в инете примеров программ отправки почты - ни одна не компилируется - все время говорит "Undeclared identifier: 'AuthenticationType"
Может кто-то все-таки знает как из Delphi 2005 почту отправить? Или у меня липа какая-то стоит? Или там копаться где-то еще надо?
А то говорят - такая типа продвинутая и удобная версия,облегчающая работу программиста...облегчение конечно большое...

Автор: <Spawn> 31.3.2005, 07:16
Хех, сумел я ее все таки запустить и вот что увидел - теперь это свойство назвается AuthType и имеет значения atDefault, atNone, atSASL smile

Автор: Snowy 31.3.2005, 07:25
Цитата
Я вообще-то диск покупал,а не скачивал.

Естественно. Я имел ввиду компоненты Indy. Их можно закачать.
Цитата
овую версию Delphi выбрасывать на помойку и взять старую?????

Судя по обсуждениям на форумах, лучше использовать D7 или D6.
Про D8 и D2005 отзывы не лучшие.
Цитата
Разве эта строка не ответственна за авторизацию на SMTP-сервере?

Она определяет тип аутентификации.
С большой долей уверенности можно сказать, что будет работать и без такого определения.

Автор: p0s0l 31.3.2005, 09:31
Перенесено из раздела Дельфи

Автор: Guest 31.3.2005, 15:53
Цитата(Snowy @ 31.3.2005, 07:25)
Цитата (Неизвестный программист @ 30.3.2005, 18:50)
Разве эта строка не ответственна за авторизацию на SMTP-сервере?

Она определяет тип аутентификации.
С большой долей уверенности можно сказать, что будет работать и без такого определения.


А как же тогда аутентификация будет? Ведь в этой строке её тип указывается! Не зря же она присуствовала в проге! Просто теперь,как выяснилось,надо писать AuthType.

Автор: Guest 31.3.2005, 15:54
Цитата
Хех, сумел я ее все таки запустить и вот что увидел - теперь это свойство назвается AuthType и имеет значения atDefault, atNone, atSASL smile

А вместо atLogin теперь писать atDefault?

Автор: Snowy 31.3.2005, 16:00
Цитата(Guest @ 31.3.2005, 15:53)
А как же тогда аутентификация будет?

Будет принято значение по умолчанию.

Цитата(Guest @ 31.3.2005, 15:54)
А вместо atLogin теперь писать atDefault?

Да. Хотя по идее она и так должна быть Default.

Автор: Неизвестный программист 1.4.2005, 02:48
Большое спасибо за ответ!А еще прошу разъяснить следующие вещи:
что означают слова nil и with
как в этой программе обрабатываются исключительные ситуации (что значит "on e:Exception do" и откуда переменная e.message).

Автор: FRAGNATIC 1.4.2005, 02:54
nil - 0 обнулить чёнить или в функцию передать если не известно значение чего либо
with - "c" тоесть с чем-то что-то делать дапустим
Код

with button1 do
begin
 и тут уже можно изменять какие-то свойства button1 но при этом бутон 1 писать не надо просто дапустим 
caption:='a';
end

Автор: Snowy 1.4.2005, 07:29
Цитата
что означают слова nil и with

nil - указатель на ничто. Применяется либо для зануления указателей (если присваиваем переменной), либо как параметр (когда хотим указать, что мы не собираемся ни на что указывать).

with - используется зля укорачивания кода. Этим словом мы указываем, что будем работать со свойствами данного объекта.
Например
Код

// вместо того, чтобы писать
Memo1.Lines.Add('первая строка')
Memo1.Lines.Add('вторая строка');
Memo1.Lines.Add('третья строка');
Memo1.Lines.Add('четвертая строка');
// можно написать так:
with Memo1.Lines do begin
  Add('первая строка');
  Add('вторая строка');
  Add('третья строка');
  Add('четвертая строка');
end;

Цитата
(что значит "on e:Exception do" и откуда переменная e.message).

Оттуда и взялась, что тут ты указал, что зовут ее так. Это обработка исключительных ситуаций. Почитай в хелпе. Создается класс-исключение. Чтобы получить его текст вручную, а не ловить стандартное окно об ошибке и требуется такая конструкция.

Автор: Неизвестный программист 1.4.2005, 16:20
Когда я убираю "try" из такого фрагмента:

// deliver message
with TIdSMTP.Create(nil) do
try
Host := smtpServer;
if (authUsername <> '') then
begin
AuthenticationType := atLogin;
Username := authUsername;
Password := authPassword;
end;
Connect;
Send(msg);
finally
Free;
end;

мне почему-то говорят:
Undeclared identifier: 'AuthType'
Undeclared identifier: 'Username'
Undeclared identifier: 'Password'
Undeclared identifier: 'Connect'
Undeclared identifier: 'Send'
Undeclared identifier: 'Free'

Ведь "try" же управляет обработкой исключительных ситуаций? Почему тогда удаление "try" так повлияло на все остальное?

Автор: _hunter 1.4.2005, 16:25
потома как ты begin забыл дописать и with начинает влиять только на первую строку

Автор: Guest 1.4.2005, 20:48
Цитата(_hunter @ 1.4.2005, 16:25)
tempora mutantur, et nos mutamur in illis

Loquerisne Latine???

Автор: Неизвестный программист 2.4.2005, 06:36
А как бы сделать так,чтобы почтовые компоненты кодировку не трогали?У меня PHP-скрипт на локальном сервере в заголовок письма вставляет "Content-Type: text/html;charset=windows-1251",а когда письмо доходит,в нем почему-то остается только "Content-Type:text/html".И тема письма становится такой: ?KOI8-R?B?0uXs4A==?=

Автор: <Spawn> 2.4.2005, 06:53
Модератор: Пожалуйста, один топик - один вопрос.

Попробуй установить кодировку в TidMessage.CharSet

Автор: Guest 2.4.2005, 20:58
Цитата
Попробуй установить кодировку в TidMessage.CharSet

Так я же не могу заранее знать,какая у всех писем кодировка!Нельзя ли сделать так,чтобы сообщение из стандартного ввода отсылалось таким,какое оно есть? Или может быть,есть другой способ отправки почты?Через сокеты например?А то в этих компонентах,я вижу,какой-то непродуманный способ формирования и отсылки писем применяется.

Автор: Неизвестный программист 4.4.2005, 04:55
Или сделать так,чтобы заголовки сообщения не изменялись.

Автор: Snowy 4.4.2005, 07:03
Цитата
чтобы почтовые компоненты кодировку не трогали?

После msg := TIdMessage.Create(nil);
Добавь msg.NoEncode:=true;

P.S. Зарегестрируйся.
Добавлено @ 07:10
Цитата
Или сделать так,чтобы заголовки сообщения не изменялись.

Не изменялись? Они создаются с нуля.
Но если тебе так важны заголовки, то удаляй ненужные из msg.HeaderList и добавляй свои.
(Если удаляешь все - то на твой страх и риск - там ведь адреса откуда-куда прописаны).
HeaderList - это TStringList, в котором находятся строки заголовка.
Дополнительно есть msg.ExtraHeaders - дополнительные заголовки, но на настройки они не влияют.

Автор: Неизвестный программист 4.4.2005, 10:14
Цитата(Snowy @ 4.4.2005, 07:03)
Цитата
чтобы почтовые компоненты кодировку не трогали?

После msg := TIdMessage.Create(nil);
Добавь msg.NoEncode:=true;

P.S. Зарегестрируйся.
Добавлено @ 07:10
Цитата
Или сделать так,чтобы заголовки сообщения не изменялись.

Не изменялись? Они создаются с нуля.
Но если тебе так важны заголовки, то удаляй ненужные из msg.HeaderList и добавляй свои.
(Если удаляешь все - то на твой страх и риск - там ведь адреса откуда-куда прописаны).
HeaderList - это TStringList, в котором находятся строки заголовка.
Дополнительно есть msg.ExtraHeaders - дополнительные заголовки, но на настройки они не влияют.

Попробовал msg.NoEncode:=true. Письма стали приходить в нормальном виде,но почему-то не работает добавка заголовков в письмо.Например,конструкция типа:

if (Msg.From.Address = '') then
if (defaultFrom = '') then
raise Exception.Create('email is missing sender''s address')
else
msg.From.Address := defaultFrom;

Почему-то defaultFrom не подстанавливается на место обратного адреса,если его нет.

Заголовки важны для указания кодировки письма.Кроме того,название темы менялось на ?koi-8? и т. д.

Заголовки не с нуля формируются,а подаются на ввод программы в готовом виде,например,серверным скриптом.

а как можно управлять заголовками через msg.HeaderList?Я и не собираюсь их все удалять - наоборот хочу оставить все как есть,и добавить,если каких-то не достает (дата,обратный адрес).

Автор: Snowy 4.4.2005, 10:36
Цитата
Заголовки не с нуля формируются,а подаются на ввод программы в готовом виде,например,серверным скриптом.

Если заголовок уже готов - не нужно подставлять всякие адреса от кого-кому - они уже в заголовке должны быть.
Просто чисти хедерлист и заполняй его своим.

Автор: Неизвестный программист 5.4.2005, 08:47
Цитата(Snowy @ 4.4.2005, 10:36)
Просто чисти хедерлист и заполняй его своим.

А можно пример?Как работать с msg.headerlist.Между прочим,я нашел только msg.header,а IdHeaderList - отдельный компонент.

Автор: Snowy 5.4.2005, 09:35
Ну да. Параметр называется header. TIdHeaderList - это класс.
header это как раз и есть параметр класса THeaderList.
А работать с ним нужно почти так же, как и с обычным TStringList.
Разница только в том, что добавление идет не через Add, а через AddStdValues.
Причем параметр обязательно должен быть вида To=mail@mail.ru
То есть параетр=значение.
Код

mgs.header.AddStdValues('from=otmenya@mail.ru');

Автор: Неизвестный программист 7.4.2005, 06:11
Я написал вот так:
if (msg.Headers.Values['From'] = '') then
msg.Headers.Values['From'] := defaultFrom;
но мне в лог-файле сказали "Bad sequence of commands".
Что это значит? И вообще в каких случаях такая надпись появляется?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)