powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / MapiSendMailW в Windows 10
18 сообщений из 18, страница 1 из 1
MapiSendMailW в Windows 10
    #39648209
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Подскажите, добрые люди, мучаюсь третий день.
После обновления на 1803 в wind10 (ну, у нас по крайней мере) перестали работать все программы, использующие WinAPI.
Это две программы от сканеров и самописная.
На этих машинах стоит The Bat, но после появления проблемы испробовали и Outlook, и Thunderbird (три разные машины, везде win10 и бат, до обновления работало).
Процедура создания исходящего письма была найдена на просторах еще лет 10 назад и работала все это время, и сейчас продолжает работать на 7ке. А вот на 10ке - фигу.
MAPISendMail возвращает код 2 MAPI_E_FAILURE One or more unspecified errors occurred. No message was sent.
Переписал модуль под использование MAPISendMailW
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
unit SendMailUnit;

interface
uses Classes, Sysutils, Forms, Winapi.Windows, Winapi.MAPI;

function SendEmail(const RecipName, RecipAddress, RecipCopyAddress,
Subject, BodyText: String; Attachment: TStringList): Boolean;

type
  PWSTR = PWideChar;
  PMapiFileDescW = ^TMapiFileDescW;
  MapiFileDescW = record
    ulReserved: ULONG;        { Reserved for future use (must be 0)     }
    flFlags: ULONG;           { Flags                                   }
    nPosition: ULONG;         { character in text to be replaced by attachment }
    lpszPathName: PWSTR;      { Full path name of attachment file       }
    lpszFileName: PWSTR;      { Original file name (optional)           }
    lpFileType: LPVOID;       { Attachment file type (can be lpMapiFileTagExt) }
  end;
  TMapiFileDescW = MapiFileDescW;

  PMapiRecipDescW = ^TMapiRecipDescW;
  MapiRecipDescW = record
    ulReserved: ULONG;       { Reserved for future use                  }
    ulRecipClass: ULONG;     { Recipient class                          }
                             { MAPI_TO, MAPI_CC, MAPI_BCC, MAPI_ORIG    }
    lpszName: PWSTR;         { Recipient name                           }
    lpszAddress: PWSTR;      { Recipient address (optional)             }
    ulEIDSize: ULONG;        { Count in bytes of size of pEntryID       }
    lpEntryID: LPVOID;       { System-specific recipient reference      }
  end;
  TMapiRecipDescW = MapiRecipDescW;

  PMapiMessageW = ^TMapiMessageW;
  MapiMessageW = record
    ulReserved: ULONG;         { Reserved for future use (M.B. 0)       }
    lpszSubject: PWSTR;        { Message Subject                        }
    lpszNoteText: PWSTR;       { Message Text                           }
    lpszMessageType: PWSTR;    { Message Class                          }
    lpszDateReceived: PWSTR;   { in YYYY/MM/DD HH:MM format             }
    lpszConversationID: PWSTR; { conversation thread ID                 }
    flFlags: FLAGS;            { unread,return receipt                  }
    lpOriginator: PMapiRecipDescW; { Originator descriptor                  }
    nRecipCount: ULONG;        { Number of recipients                   }
    lpRecips: PMapiRecipDescW;  { Recipient descriptors                  }
    nFileCount: ULONG;         { # of file attachments                  }
    lpFiles: PMapiFileDescW;    { Attachment descriptors                 }
  end;
  TMapiMessageW = MapiMessageW;

  TFNMapiSendMailW = function(lhSession: LHANDLE; ulUIParam: ULONG_PTR;
    var lpMessage: TMapiMessageW; flFlags: FLAGS;
    ulReserved: ULONG): ULONG stdcall;

implementation

var
 sendMailW : TFNMapiSendMailW;
 MAPIModule: HModule = 0;
 MAPIDLL: string = 'MAPI32.DLL';

function MapiSendMailW(lhSession: LHANDLE; ulUIParam: ULONG_PTR;
  var lpMessage: TMapiMessageW; flFlags: FLAGS; ulReserved: ULONG): ULONG;
begin
  MAPIModule := LoadLibrary(PChar(MAPIDLL));
  @SendMailW := GetProcAddress(MAPIModule, 'MAPISendMailW');
  if @SendMailW <> nil then
    Result := SendMailW(lhSession, ulUIParam, lpMessage, flFlags, ulReserved)
  else Result := 2;
end;

function SendEmailAnsi(const RecipName, RecipAddress, RecipCopyAddress,
Subject, BodyText: String; Attachment: TStringList): Boolean;
var
  MapiMessage: TMapiMessage;
  MapiFileDesc: array of TMapiFileDesc;
  MapiRecipDesc: array of TMapiRecipDesc;
  i: integer;
begin

  if RecipCopyAddress<>'' then
  begin
  SetLength(MapiRecipDesc, 2);
  with MapiRecipDesc[0] do
  begin
    ulReserved := 0;
    ulRecipClass := MAPI_TO;
    lpszName := PAnsiChar(AnsiString(RecipName));
    lpszAddress := PAnsiChar(AnsiString(RecipAddress));
    ulEIDSize := 0;
    lpEntryID := nil;
  end;
  with MapiRecipDesc[1] do
  begin
    ulReserved := 0;
    ulRecipClass := MAPI_CC;
    lpszName := PAnsiChar(AnsiString(RecipName));
    lpszAddress := PAnsiChar(AnsiString(RecipCopyAddress));
    ulEIDSize := 0;
    lpEntryID := nil;
  end;
  end else
  begin
  SetLength(MapiRecipDesc, 1);
  with MapiRecipDesc[0] do
  begin
    ulReserved := 0;
    ulRecipClass := MAPI_TO;
    lpszName := PAnsiChar(AnsiString(RecipName));
    lpszAddress := PAnsiChar(AnsiString(RecipAddress));
    ulEIDSize := 0;
    lpEntryID := nil;
  end;
  end;

   SetLength(MapiFileDesc, Attachment.Count);
   for i := 0 to Attachment.Count - 1 do
      with MapiFileDesc[i] do
      begin
         ulReserved:= 0;
         flFlags:= 0;
         nPosition:= i;
         lpszPathName:= PAnsiChar(AnsiString(Attachment.Strings[i]));
         lpszFileName:= nil;
         lpFileType:= nil;
      end;

  with MapiMessage do
  begin
    ulReserved := 0;
    lpszSubject := PAnsiChar(AnsiString(Subject));
    lpszNoteText := PAnsiChar(AnsiString(BodyText));
    lpszMessageType := nil;
    lpszDateReceived := nil;
    lpszConversationID := nil;
    flFlags := 0;
    lpOriginator := nil;
    if RecipCopyAddress<>'' then
      nRecipCount := 2 else
      nRecipCount := 1;
    lpRecips := @MapiRecipDesc[0];
    if Attachment.Count > 0 then
    begin
      nFileCount:= Attachment.Count;
      lpFiles := @MapiFileDesc[0];
    end
    else
    begin
      nFileCount:= 0;
      lpFiles:= nil;
    end;
  end;

  i := MapiSendMail(0, Application.Handle, MapiMessage, MAPI_DIALOG
  or MAPI_LOGON_UI or MAPI_NEW_SESSION, 0);
  Result:= i = SUCCESS_SUCCESS;
end;

function SendEmailW(const RecipName, RecipAddress, RecipCopyAddress,
Subject, BodyText: String; Attachment: TStringList): Boolean;
var
  MapiMessageW: TMapiMessageW;
  MapiFileDescW: array of TMapiFileDescW;
  MapiRecipDescW: array of TMapiRecipDescW;
  i: integer;
begin

  if RecipCopyAddress<>'' then
  begin
  SetLength(MapiRecipDescW, 2);
  with MapiRecipDescW[0] do
  begin
    ulReserved := 0;
    ulRecipClass := MAPI_TO;
    lpszName := PChar(RecipName);
    lpszAddress := PChar(RecipAddress);
    ulEIDSize := 0;
    lpEntryID := nil;
  end;
  with MapiRecipDescW[1] do
  begin
    ulReserved := 0;
    ulRecipClass := MAPI_CC;
    lpszName := PChar(RecipName);
    lpszAddress := PChar(RecipCopyAddress);
    ulEIDSize := 0;
    lpEntryID := nil;
  end;
  end else
  begin
  SetLength(MapiRecipDescW, 1);
  with MapiRecipDescW[0] do
  begin
    ulReserved := 0;
    ulRecipClass := MAPI_TO;
    lpszName := PChar(RecipName);
    lpszAddress := PChar(RecipAddress);
    ulEIDSize := 0;
    lpEntryID := nil;
  end;
  end;

   SetLength(MapiFileDescW, Attachment.Count);
   for i := 0 to Attachment.Count - 1 do
      with MapiFileDescW[i] do
      begin
         ulReserved:= 0;
         flFlags:= 0;
         nPosition:= i;
         lpszPathName:= PChar(Attachment.Strings[i]);
         lpszFileName:= nil;
         lpFileType:= nil;
      end;

  with MapiMessageW do
  begin
    ulReserved := 0;
    lpszSubject := PChar(Subject);
    lpszNoteText := PChar(BodyText);
    lpszMessageType := nil;
    lpszDateReceived := nil;
    lpszConversationID := nil;
    flFlags := 0;
    lpOriginator := nil;
    if RecipCopyAddress<>'' then
      nRecipCount := 2 else
      nRecipCount := 1;
    lpRecips := @MapiRecipDescW[0];
    if Attachment.Count > 0 then
    begin
      nFileCount:= Attachment.Count;
      lpFiles := @MapiFileDescW[0];
    end
    else
    begin
      nFileCount:= 0;
      lpFiles:= nil;
    end;
  end;

  i := MapiSendMailW(0, Application.Handle, MapiMessageW, MAPI_DIALOG
  or MAPI_LOGON_UI or MAPI_NEW_SESSION, 0);
  MessageBox(Application.Handle, Pchar(IntToStr(i)), '', 0);
  Result:= i = SUCCESS_SUCCESS;
end;


function SendEmail(const RecipName, RecipAddress, RecipCopyAddress,
Subject, BodyText: String; Attachment: TStringList): Boolean;
begin
  Result := SendEmailW(RecipName, RecipAddress, RecipCopyAddress, Subject, BodyText, Attachment);
end;

end.



MapiSendMailW возвращает ту же 2 MAPI_E_FAILURE

Блин, что ему надо, а, подскажите? :(
PS меняли программы по умолчанию, вот так выглядит реестр на данный момент:
Код: xml
1.
2.
3.
4.
5.
[HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail]
@="The Bat!"
[HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail\The Bat!]
"DLLPath"="C:\\Program Files\\The Bat!\\TBMapi64.dll"
@="The Bat!"



Спасибо!
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648210
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Использующие WinAPI Simple MAPI :)
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648212
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Программа 32-x битная?
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648213
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskin, да. Пробовали 32битный Бат, 32битный Thunderbird - тот же результат
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648215
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В уведомлениях отладчика DLL-то загружается?
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648221
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker,

Код: pascal
1.
2.
if @SendMailW <> nil then
    Result := SendMailW(lhSession, ulUIParam, lpMessage, flFlags, ulReserved) //сюда выполнение заходит

или как-то еще надо посмотреть?
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648222
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
View / Debug Windows / Event log.

Ну или Process Monitor-ом.
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648223
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нужно смотреть, загружена ли TBMapi32.dll
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648224
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И посмотри ветку HKEY_CURRENT_USER\Software\Clients\Mail, а не HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail.
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648229
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще вспомнил. Не знаю, какая у тебя версия The Bat, но старые версии имели неправильную реализацию MAPISendMailW, ошибка исправлена начиная с версии 7.4.16.
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648234
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Благодарю за варианты!
Модуль dll грузится:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
Process regindoc.exe (9012)
Source Breakpoint at $00FF3743: C:\Project\DMITRY\!XE2\RegInDoc\SendMailUnit.pas line 65. Process regindoc.exe (9012)
Module Load: MAPI32.dll. No Debug Info. Base Address: $642A0000. Process regindoc.exe (9012)
Thread Start: Thread ID: 3028. Process regindoc.exe (9012)
Thread Start: Thread ID: 12776. Process regindoc.exe (9012)
Thread Start: Thread ID: 476. Process regindoc.exe (9012)
Thread Start: Thread ID: 13340. Process regindoc.exe (9012)
Module Load: Windows.StateRepositoryPS.dll. No Debug Info. Base Address: $64CA0000. Process regindoc.exe (9012)
Thread Exit: Thread ID: 3028. Process regindoc.exe (9012)


Но не вижу чтобы грузился TBMAPI. Или тут и не покажет?
Ветка в CURRENT_USER пустая, и какая-то разная реакция именно при изменении ветки в LOCAL_MACHINE
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648241
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Лог нужно смотреть как минимум после вызова MAPISendMailW. И все же определись, у тебя активен 32 битный MAPI провайдер или 64 битный?
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648246
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskin, да, у нас 7.1...
Но тогда вопросы :)
Почему раньше работала обычная функция с PAnsiChar MAPISendMail, а сейчас нет.
Почему сейчас не работает и Thunder, и Outlook даже с MAPISendMailW.
И если бы только у меня накрылось... а накрылось то три машины и именно после обновления.
И не только моя программа, но и другие, которые так же открывали диалоги.
Не нашел чтобы еще кто-то жаловался, значит что-то у меня :(


Винда 64битная. Бат стоит 64битный. Его tbmapi64.dll и указал (но пробовал и 32). Программа 32битная.
Но имхо этот вопрос рассматривать не надо, потому что раньше работало :) При тех же разрядностях.
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648254
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DevillioПочему раньше работала обычная функция с PAnsiChar MAPISendMail, а сейчас нет.
Почему сейчас не работает и Thunder, и Outlook даже с MAPISendMailW.Потому что где то у кого то что изменилось в окружении.

DevillioИ если бы только у меня накрылось... а накрылось то три машины и именно после обновления.У меня Win10 со всеми обновлениями, все как работало, так и работает.

DevillioНе нашел чтобы еще кто-то жаловался, значит что-то у меня :(Дебаггер в руки и изучать, что же у тебя.

DevillioВинда 64битная. Бат стоит 64битный. Его tbmapi64.dll и указал (но пробовал и 32). Программа 32битная. Программа 32битная. Но имхо этот вопрос рассматривать не надо32 битные программы могут использовать только 32 битный MAPI провайдер. 64 битные программы могут использовать только 64 битный MAPI провайдер. Соответственно, если у тебя 32 битная программа, то должен быть установлен 64 битный MAPI провайдер. Но если ты считаешь это не существенным, то ок, я устраняюсь.
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648256
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
* Соответственно, если у тебя 32 битная программа, то должен быть установлен 32 битный MAPI провайдер *
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648292
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aniskin, благодарю за помощь.
Поставил на "чистую" винду все (там все пошло), заметил что в реестре почтовое приложение по умолчанию указывается в ветке "CURRENT_USER", а сами описания почтовых программ - в "LOCAL_MACHINE". Еще снес 64битный Бат, в реестре поделал замены на bat32 - и все пошло!
Т.е. как бы "32 битный MAPI провайдер" установлен, если вашими словами.
Для проверки свое приложение пересобрал для платформы x64 - так же все работает. Так что не знаю )) должно пахать и так и так, и по логике тоже - а иначе во всей винде будет эта функция доступна или 32битным, или 64битным, а должно всем.
Так что проблема была, похоже, в расположении указания на приложение по умолчанию.
Сори за топик в Delphi, проблема оказалась не текстах )))
Еще раз благодарю всех за помощь!
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648299
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Devillioдолжно пахать и так и так, и по логике тоже - а иначе во всей винде будет эта функция доступна или 32битным, или 64битным, а должно всем.

Я извиняюсь, я совсем забыл, что MAPISendMail является исключением и для нее Windows создает proxy процесс.
https://msdn.microsoft.com/en-us/library/office/dd941355.aspx
...
Рейтинг: 0 / 0
MapiSendMailW в Windows 10
    #39648302
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
https://msdn.microsoft.com/en-us/library/dd296734(v=vs.85).aspx

The use of Simple MAPI is discouraged. It may be altered or unavailable in subsequent versions of Windows

Как-то так...
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / MapiSendMailW в Windows 10
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]