Проблема, с которой сталкиваются разработчики, использующие Delphi для отправки электронных писем через MS Office Outlook, заключается в возникновении ошибки EOlesystem error: Operation unavailable при попытке выполнить операцию, если Outlook не запущен. Это приводит к тому, что выполнение кода не достигает блока except, что делает невозможным обработку возникшей ошибки.
Пример кода, вызывающего ошибку:
procedure TMyform.BTN_mailClick(Sender: TObject);
const
olMailItem = 0;
var
Outlook: OleVariant;
vMailItem: variant;
begin
try
Outlook := GetActiveOleObject('Outlook.Application');
except
Outlook := CreateOleObject('Outlook.Application');
end;
vMailItem := Outlook.CreateItem(olMailItem);
vMailItem.Recipients.Add(mailaddress);
// ... остальной код ...
vMailItem.Send;
// ... очистка ...
end;
Подтвержденный ответ:
Чтобы решить проблему, следует использовать проверку на активность объекта Outlook перед его использованием. Это можно сделать с помощью следующего кода:
var
Outlook: OleVariant;
ClassID: TCLSID_OutlookApp;
Unknown: IUnknown;
begin
if Succeeded(GetActiveObject(ClassID_OutlookApp, nil, Unknown)) then
OleCheck(Unknown.QueryInterface(IDispatch, Outlook)) else
Outlook := CreateOleObject('Outlook.Application');
// ... остальной код ...
end;
Также полезно использовать альтернативный способ добавления получателей, предложенный в альтернативном ответе:
Это может помочь избежать ошибок, связанных с добавлением адресатов, и упростить процесс.
Альтернативные подходы:
Использование VarClear(Outlook) после выполнения всех операций и закрытия Outlook.
Проверка, что Outlook запущен, перед созданием новых объектов сообщений.
Использовать Mail.Display вместо Mail.Send при разработке, чтобы можно было визуально проверить сообщение перед отправкой (отправка напрямую может быть активирована установкой Mail.Send после тщательной проверки).
Пример обновленного кода:
procedure TForm1.SendMailClick(Sender: TObject);
const
olMailItem = $00000000;
var
Outlook, Mail: OleVariant;
begin
if OutlookIsRunning then
Outlook := GetActiveOleObject('Outlook.Application') else
Outlook := CreateOleObject('Outlook.Application');
try
Mail := Outlook.CreateItem(olMailItem);
Mail.To := 'receiver@example.com';
Mail.Subject := 'Your Subject';
Mail.Body := 'Your message body goes here';
Mail.Display; // Отображает сообщение, для отправки напрямую используйте Mail.Send
except
on E: Exception do
ShowMessageFmt('Error: %s, Message: %s', [E.ClassName, E.Message]);
end;
// Не забудьте освободить ресурсы, если это необходимо
// VarClear(Outlook);
end;
function OutlookIsRunning: Boolean;
var
ClassID_OutlookApp: TCLSID;
IUnknown: IUnknown;
begin
Result := Succeeded(GetActiveObject(ClassID_OutlookApp, nil, IUnknown));
end;
Важно:
Убедитесь, что в вашем проекте Delphi используется корректный TCLSID_OutlookApp, соответствующий версии Outlook, с которой вы работаете.
При работе с объектами OLE не забывайте о корректном освобождении ресурсов, где это необходимо, используя VarClear.
Применение этих методов позволит разработчикам избежать ошибки EOlesystem error: Operation unavailable и обеспечит более надежную отправку писем через Outlook в приложениях, созданных с использованием Delphi.
с отправкой писем в Delphi 2006 через Outlook, связанной с ошибкой OLESystemError при отсутствии запущенного Outlook.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.