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

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

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

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

Ну или Process Monitor-ом.
...
Рейтинг: 0 / 0
22.05.2018, 16:43
    #39648223
Aniskin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MapiSendMailW в Windows 10
Нужно смотреть, загружена ли TBMapi32.dll
...
Рейтинг: 0 / 0
22.05.2018, 16:45
    #39648224
Aniskin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MapiSendMailW в Windows 10
И посмотри ветку HKEY_CURRENT_USER\Software\Clients\Mail, а не HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail.
...
Рейтинг: 0 / 0
22.05.2018, 16:56
    #39648229
Aniskin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MapiSendMailW в Windows 10
И еще вспомнил. Не знаю, какая у тебя версия The Bat, но старые версии имели неправильную реализацию MAPISendMailW, ошибка исправлена начиная с версии 7.4.16.
...
Рейтинг: 0 / 0
22.05.2018, 17:01
    #39648234
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MapiSendMailW в Windows 10
Благодарю за варианты!
Модуль 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
22.05.2018, 17:08
    #39648241
Aniskin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MapiSendMailW в Windows 10
Лог нужно смотреть как минимум после вызова MAPISendMailW. И все же определись, у тебя активен 32 битный MAPI провайдер или 64 битный?
...
Рейтинг: 0 / 0
22.05.2018, 17:15
    #39648246
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MapiSendMailW в Windows 10
Aniskin, да, у нас 7.1...
Но тогда вопросы :)
Почему раньше работала обычная функция с PAnsiChar MAPISendMail, а сейчас нет.
Почему сейчас не работает и Thunder, и Outlook даже с MAPISendMailW.
И если бы только у меня накрылось... а накрылось то три машины и именно после обновления.
И не только моя программа, но и другие, которые так же открывали диалоги.
Не нашел чтобы еще кто-то жаловался, значит что-то у меня :(


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

Я извиняюсь, я совсем забыл, что MAPISendMail является исключением и для нее Windows создает proxy процесс.
https://msdn.microsoft.com/en-us/library/office/dd941355.aspx
...
Рейтинг: 0 / 0
22.05.2018, 19:47
    #39648302
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MapiSendMailW в Windows 10
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
Форумы / Delphi [игнор отключен] [закрыт для гостей] / MapiSendMailW в Windows 10 / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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