X mailer microsoft cdo for windows 2000

Продолжаем разговор о почтовой системе Windows. CDO для Windows 2000 - новый API для работы с SMTP и NNTP сервисами NT. Check this out.

Продолжаем разговор о почтовой системе Windows. CDO для Windows 2000 — новый API для работы с SMTP и NNTP сервисами NT. Check this out.

Краткий обзор технологий

Приходилось ли вам программно отправлять почту или получать доступ к сообщениям вашего почтового ящика? Если вы программировали эти задачи на Visual C++, то наверняка вам знаком интерфес MAPI. Но о нем говорить, к счастью, не будем.

Bо времена Exchange 5.0 cуществовал и более легкий способ работы с почтовыми сообщениями — при помощи библиотеки OLEMSG32, которая по сути была COM оберткой для MAPI. С появлением Exchange 5.5 Microsoft сменил название библиотеки, сделав его весомым и кратким — CDO (Collaboration Data Object). Функциональность же принципиально не изменилась.

Библиотеки CDO ранних версий ( CDO v 1.x ) основывались на интерфейсах MAPI, и предоставляли разработчикам способы управления почтовыми сообщениями проще чем MAPI. За счет этого программирование при помощи CDO стало популярно среди разработчиков. Для доступа к компонентам SMTP и NNTP, входящим в состав IIS 4.0 появилась библиотека CDONTS — специализированное подмножество CDO.

Вместе с Windows 2000 вышла библиотека CDO 2.0 или CDO for Windows 2000. Основой для нее явились принципиально новые решения: поддержка Internet-стандартов и стандартизация доступа к данным через OLE DB/ADO интерфейс. Известно, что операционная система Windows 2000 активно использует эту библиотеку для своих задач.

С выходом Exchange 2000 на свет появилась еще несколько библиотек CDO — 3.0 или CDO for Exchange 2000, CDO for Exchange Management и CDO Workflow Objects for Exchange. CDO for Exchange естественно расширяет функциональность CDO for Windows. С помощью CDO 3.0 возможна разработка программных решения на базе Web Store. А наличие механизмов перехвата транспорнтых событий и событий от операций с даннымии ( transport and store event) позволяет расширять функциональность Web Store.

Примечание: Web Store — одна из ключевых инициатив Microsoft для унификации доступа к данным. Web Store комбинирует функциональность файловой системы, Web — доступа и процедур коллективной работы.

Далее не будем вспоминать, что было в веке минувшем и подробнее остановимся на версиях CDO, поставляемых с продуктами Microsoft версии 2000.

Основные черты CDO for Windows 2000 (CDOSYS.DLL)

  • Для работы через CDOSYS необходимы ОС Windows 2000 и сервер SMTP ( локальный или удаленный ). Возможна программная настройка на SMTP сервер.
  • Поддержка транспортных событий. События протоколов для входящей и исходящей почты и новостей. Поддержка Internet — стандартов.
  • Создание и управление данными в форматах MIME/MHTML. Поддержка отправки/приема сообщений через SMTP/NNTP протоколы.
  • Стандартизованный доступ к данным. CDOSYS основана на технологии доступа к данным OLE DB/ADO.
  • Поддержка языков программирования. CDOSYS — это COM библиотека, поддерживающая дуальный интерфейс, что позволяет использовать ее во многих языках программирования: Visual Basic, VB Scripting Edition, Java Script, Visual Basic for Application, Visual C++.
  • Возможность обновления библиотеки. CDOSYS разрабатывалась как подмножество библиотеки CDO for Exchange (CDOEX). Поэтому поддерживается полная программная совместимость приложений, разработанных для CDOSYS после установки Exchange 2000.

Cценарии применения CDOSYS.DLL

  • Массовые рассылки. Создание шаблонов сообщений.
  • Репликации, основанные на почтовых сообщениях. Например, Windows 2000 использует CDOSYS для репликаций Active Directory.
  • Проверка на наличие вирусов в почтовых сообщениях и новостях перед доставкой получателю.
  • Выявление spam — сообщений перед доставкой получателю.
  • Отправка Web — страниц, включая ссылки и графику по запросам пользователей. Например, организация подписки на страницы с новостями.
  • Формирование и отправка сообщений, подтверждающих завершение транзакций.
  • Автоматическая пересылка входящей почты.
  • Административные сообщения.Например, периодическая отправка сообщений о состоянии серверов/сервисов в почтовый ящик системного администратора.

Основные черты CDO for Exchange Server 2000 (CDOEX.DLL)

  • Расшираяет функциональность CDO for Windows. Поддерживается программная совместимость с CDOSYS.
  • Управление календарем через CDOEX. Протокол работы c кадендарем основан на стандартах Internet (iCalendar). Поддерживается полная совместимость с календарем Outlook 98 и Outlook 2000.
  • Разделение функциональности. ADO используется для навигации по данным а CDO для связывания с Web Store.
  • Создание пользовательских объектов CDO. CDOEX позволяет имплементировать базовые объекты CDO при создании пользовательских CDO объектов.
  • Дополнительные библиотеки для Exchange Server 2000. Библиотека CDOEXM — CDO for Exchange Mangement Libraries предоставляет объекты и интерфейсы для управления сервером и почтовыми ящиками Exchange Server. Для обеспечения доступа к Active Directory Microsoft рекомендует использовать эту библиотеку соместно с интерфейсами ADSI (Active Directory Service Interfaces). Еще одна новая библиотека CDOWF служит для управления объектами Exchange Workflow Engine.

Версии CDO

Exchange 5.0 Exchange 5.5 IIS 4.0 Windows 2000 Server Exchange 2000
Active Messaging

Да

Нет

Нет

Нет

Нет

CDO 1.2

Нет

Да

Нет

Нет

Да

CDO 1.2 for Windows NT Server

Нет

Да

Да

Да*

Да*

CDO for Windows 2000 Server

Нет

Нет

Нет

Да

Нет

CDO for Exchange 2000

Нет

Нет

Нет

Нет

Да

* — поддерживается для совместимости с существующими приложениями.

Примеры создания объектов библиотеки CDO в разных языках программирования

VbScript

Dim iMsg
Set iMsg = CreateObject("CDO.Message")
Dim iDsrc
Set iDsrc = iMsg.DataSource
Dim iBp
Set iBp = iMsg.BodyPart

Visual Basic
Предварительно необходимо установить ссылки на Microsoft CDO for Microsoft Windows 2000 Library Microsoft ActiveX Data Objects 2.5 Library

Dim iMsg As New CDO.Message
...

Visual C++
Если вы хотите работать с объектами CDOSYS на языке С++, используя только COM, то основа программы будет выглядеть следующим образом:

#import "c:program filescommon filessystemadomsado15.dll"
no_namespace raw_interfaces_only #import "cdosys.dll" no_namespace raw_interfaces_only /* Флаг raw_interfaces_only запрещает создание классов - оберток для использования "смарт-поинтеров". По флагу no_namespace не просиходит генерации компилятором пространста имен. */ #include "с:sdkincludecdosysstr.h" #include "с:sdkincludecdosyserr.h" #include <assert.h> void main() { CoInitialize(NULL); IMessage* pMsg = NULL; HRESULT hr = CoCreateInstance(__uuidof(Message), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMessage), reinterpret_cast<void**>(&pMsg)); assert(SUCCEEDED(hr)); Fields* pFlds = NULL; pMsg->get_Fields(&pFlds); ... CoUninitialize(); }

Важное замечание
Обязательно нужно использовать ADO 2.5 в глобальном пространстве имен или в пространстве имен CDO. Иначе по умолчанию параметры в функциях CDO из пространства имен ADO не будут корректно разрешены при компиляции.

Пример использования классов — оберток

#import "c:program filescommon filessystemadomsado15.dll"
no_namespace #import
"c:program filescommon filesMicrosoft SharedCDOcdoex.dll" no_namespace #include "cdoexstr.h" #include "cdoexerr.h" void main() { CoInitialize(NULL); { try { IMessagePtr iMsg(__uuidof(Message)); FieldsPtr Flds; Flds = iMsg->Fields; : } catch( _com_error err) { // ... } } CoUninitialize(); return 1; }

Объектная модель CDO 2.0

  • IBodyPart — содержит абстрактные методы и свойства для управления секции тела сообщения.
  • IMessage — содержит абстрактные методы и свойства для управления сообщением в целом.
  • IDataSource — содержит абстрактные методы и свойства для связывания и упорядочивания, выделения и вставки данных сообщений в другие объекты или из них.
  • IDropDirectory — содержит методы доступа к сообщениям, хранящимся в файловой системе (например в Windows 2000 SMTP drop directory).
  • IMessages — содержит интерфейс коллекции сообщений.
  • IBodyParts — содержит интерфейс коллекции секций сообщения.

Аннотация

Библиотеки объектов данных совместной работы (все версии) используются для реализации функций обмена сообщениями и совместной работы в настраиваемом приложении. В этой статье приведены сведения о том, где можно найти эти библиотеки.

Дополнительная информация

Библиотеки динамической компоновки (DLL) для объектов CDO (1,1, 1,2, 1,21) и CDO (1,1, 1,2) — это клиентские библиотеки объектов MAPI. Таким образом, для них требуются MAPI и поставщики услуг (например, те же поставщики услуг, что и в Microsoft Exchange Server).

Объекты совместной работы для NTS (CDONTS) — это простой протокол передачи почты (SMTP), который является частью общей библиотеки CDO (1,1, 1,2), но не зависит от MAPI.

Объекты совместной работы для Windows 2000 (CDOSYS) — это тактовый скачок в обмене сообщениями SMTP через CDONTS. CDOSYS обеспечивает обширный контент с помощью расширенной поддержки MIME.

Имена этих файлов варьируются в зависимости от версии CDO, как указано в приведенной ниже таблице.

Версия

Библиотека сообщений
ПУСТИВ

Отрисовка библиотеки
Rnd

CDO для NTS
(NTS)

CDO для Win2K
ПУБЛИКАЦИИ

v1.1

Olemsg32.dll

Amhtml.dll

Cdonts.dll

n/a

v1.2

Cdo.dll

Cdohtml.dll

Cdonts.dll

n/a

v1.21

Cdo.dll

Cdohtml.dll

n/a

n/a

v6.0

n/a

n/a

n/a

Cdosys.dll

Эти файлы можно получить при установке следующих продуктов:

v1.1

v1.2

v1.21

v6.0

ПУСТИВ

RND

NTS

ПУСТИВ

RND

NTS

ПУСТИВ

RND

NTS

ПУБЛИКАЦИИ

Outlook 8,00

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Клиент Exchange 5,0

Д

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Outlook 8.01 — 8.03

Д

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Сервер Exchange 5,0

Д

Д

Д

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

IIS 4,0

.Nn-

.Nn-

Д

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Outlook 98

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

.Nn-

.Nn-

.Nn-

Сервер Exchange 5,5

.Nn-

.Nn-

.Nn-

Д

Д

Д

.Nn-

.Nn-

.Nn-

.Nn-

Exchange 5,5 Server SP1

.Nn-

.Nn-

.Nn-

.Nn-

Д

Д

Д

.Nn-

.Nn-

.Nn-

Сервер Exchange 5,5 с пакетом обновления 2

.Nn-

.Nn-

.Nn-

.Nn-

Д

Д

Д

.Nn-

.Nn-

.Nn-

Outlook 2000

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

.Nn-

.Nn-

.Nn-

Outlook 2002

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

.Nn-

.Nn-

.Nn-

Outlook 2003

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

.Nn-

.Nn-

.Nn-

Windows 2000

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

Exchange 2000

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

Д

.Nn-

.Nn-

Exchange 2000 SP1

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

Д

.Nn-

.Nn-

Exchange 2000 SP2

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

Д

.Nn-

.Nn-

Exchange 2000 SP3

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

Д

.Nn-

.Nn-

Windows 2003

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

Exchange 2003

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

.Nn-

Д

.Nn-

.Nn-

.Nn-

Начиная с Microsoft Exchange Server 2007 Beta 2, в них не включены клиентские библиотеки API обмена сообщениями (MAPI) и CDO 1.2.1. Таким образом, функции отсутствуют, и многие приложения зависят от этих функциональных возможностей. Microsoft Exchange MAPI и CDO 1.2.1 предоставляют доступ к этим API. Эти API предоставляют доступ к содержимому хранилищ MAPI.

Примечание. Поскольку эта версия CDO входит в состав Exchange 2003, мы не поддерживаем установку этой версии на компьютере с установленным приложением Outlook. Дополнительные сведения см. в следующей статье базы знаний Майкрософт:

266418 Корпорация Майкрософт не поддерживает установку компонентов Exchange Server и Outlook на одном и том же компьютере
 
Для компьютеров, использующих Outlook 2010, использование CDO не поддерживается. Для получения дополнительных сведений обратитесь к следующей статье Microsoft Knoowledge Base:

Объекты данных совместной работы (CDO) 1.2.1 не поддерживаются в Outlook 2010

Примечание. Компонент CDO версии 1.2.1 ссылается на версию API, которая не является версией DLL, реализующей API. Библиотека DLL, содержащаяся в Outlook 2007 CDO download, имеет версию 6,5. Это не обновление CDOSYS, на которое ссылается эта статья, как версия 6,0.

При использовании Exchange для установки CDO 1,21 можно использовать один из указанных ниже способов для установки.

  • Установка Exchange Server (Exchange 5,5, 2000 и 2003)

  • Установка только служебной программы Exchange Administrator (или Exchange System Manager) (Exchange 5,5, 2000 и 2003)

  • Установка Outlook Web Access (OWA — только Exchange 5,5)

После установки может потребоваться вручную зарегистрировать CDO. dll с помощью Regsrv32 (то есть Regsrv32. exe полный путь и имя файла для CDO. DLL). Для установки Exchange System Manager необходимо скопировать файл CDO. dll с установочного носителя в каталог% Program Files%/Exchsrvr/Bin, прежде чем регистрировать CDO. dll с помощью Regsrv32. exe.

По умолчанию установки Outlook не включают компонент CDO 1.2 x. При просмотре параметров настройки Office или Outlook компонент CDO отображается в разделе Параметры для Outlook.

Нужна дополнительная помощь?

Такой вариант через yandex.ru работает. А на внутренней почте появляется ошибка «Нет доступа к Интернет». Но там интернет и не нужен.  
Кто знает, как поступить в этом случае?    

  Sub Send_Mail()  
   Const CDO_Cnf = «http://schemas.microsoft.com/cdo/configuration/»  
   Dim oCDOCnf As Object, oCDOMsg As Object  
   Dim SMTPserver As String, sUsername As String, sPass As String, sMsg As String  
   Dim sTo As String, sFrom As String, sSubject As String, sBody As String, sAttachment As String  
   On Error Resume Next  
   ‘sFrom — как правило совпадает с sUsername  
   SMTPserver = [B10] ‘ SMTPServer: для Mail.ru «smtp.mail.ru»; для Яндекса «smtp.yandex.ru»; для Рамблера «mail.rambler.ru»
   sUsername = [B11] ‘ Учетная запись на сервере
   sPass = [B12] ‘ Пароль к почтовому аккаунту

     If Len(SMTPserver) = 0 Then MsgBox «Не указан SMTP сервер», vbInformation, «www.Excel-VBA.ru»: Exit Sub  
   If Len(sUsername) = 0 Then MsgBox «Не указана учетная запись», vbInformation, «www.Excel-VBA.ru»: Exit Sub  
   If Len(sPass) = 0 Then MsgBox «Не указан пароль», vbInformation, «www.Excel-VBA.ru»: Exit Sub  

     sTo = [B2] ‘Кому
   sFrom = [B3] ‘От кого
   sSubject = [B4] ‘Тема письма
   sBody = [B5] ‘Текст письма
   ‘sAttachment = [B6] ‘Вложение(полный путь к файлу)
   sAttachment = Cells(6, «B»).Value  
   ‘Проверка наличия файла по указанному пути  
   If Dir(sAttachment, vbDirectory) = «» Then sAttachment = «»  
   ‘Назначаем конфигурацию CDO  
   Set oCDOCnf = CreateObject(«CDO.Configuration»)  
   With oCDOCnf.Fields  
       .Item(CDO_Cnf & «sendusing») = 2  
       .Item(CDO_Cnf & «smtpauthenticate») = 1  
       .Item(CDO_Cnf & «smtpserver») = SMTPserver  
       .Item(CDO_Cnf & «sendusername») = sUsername  
       .Item(CDO_Cnf & «sendpassword») = sPass  
       .Update  
   End With  
   ‘Создаем сообщение  
   Set oCDOMsg = CreateObject(«CDO.Message»)  
   With oCDOMsg  
       Set .Configuration = oCDOCnf  
       .BodyPart.Charset = «koi8-r»  
       .From = sFrom  
       .To = sTo  
       .Subject = sSubject  
       .TextBody = sBody  
       ‘.AddAttachment = sAttachment  
       If Len(sAttachment) > 0 Then .AddAttachment sAttachment  

         .Send  
   End With  

     Select Case Err.Number  
   Case -2147220973: sMsg = «Нет доступа к Интернет»  
   Case -2147220975: sMsg = «Отказ сервера SMTP»  
   Case 0: sMsg = «Письмо отправлено»  
   End Select  
   MsgBox sMsg, vbInformation, «Проверка доступа в Интернет»  
   Set oCDOMsg = Nothing: Set oCDOCnf = Nothing  
End Sub

The CDO2000 class allows to send emails w/o user intervention using a SMTP server.

.

is included in Windows 2000 and later.

. The default is «us-ascii».

  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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

* CDO2000.prg

#DEFINE cdoSendPassword "http://schemas.microsoft.com/cdo/configuration/sendpassword"
#DEFINE cdoSendUserName "http://schemas.microsoft.com/cdo/configuration/sendusername"
#DEFINE cdoSendUsingMethod "http://schemas.microsoft.com/cdo/configuration/sendusing"
#DEFINE cdoSMTPAuthenticate "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"
#DEFINE cdoSMTPConnectionTimeout "http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout"
#DEFINE cdoSMTPServer "http://schemas.microsoft.com/cdo/configuration/smtpserver"
#DEFINE cdoSMTPServerPort "http://schemas.microsoft.com/cdo/configuration/smtpserverport"
#DEFINE cdoSMTPUseSSL "http://schemas.microsoft.com/cdo/configuration/smtpusessl"
#DEFINE cdoURLGetLatestVersion "http://schemas.microsoft.com/cdo/configuration/urlgetlatestversion"
#DEFINE cdoAnonymous 0	&& Perform no authentication (anonymous)
#DEFINE cdoBasic 1	&& Use the basic (clear text) authentication mechanism.
#DEFINE cdoSendUsingPort 2	&& Send the message using the SMTP protocol over the network.
#DEFINE cdoXMailer "urn:schemas:mailheader:x-mailer"

DEFINE CLASS cdo2000 AS Custom

	PROTECTED aErrors[1], nErrorCount, oMsg, oCfg, cXMailer

	nErrorCount = 0

	* Message attributes
	oMsg = Null
		
	cFrom = ""
	cReplyTo = ""
	cTo = ""
	cCC = ""
	cBCC = ""
	cAttachment = ""

	cSubject = ""
	cHtmlBody = ""
	cTextBody = ""
	cHtmlBodyUrl = ""

	cCharset = ""

	* Priority: Normal, High, Low or empty value (Default)
	cPriority = ""

	* Configuration object fields values
	oCfg = Null
	cServer = ""
	nServerPort = 25
	* Use SSL connection
	lUseSSL = .F.
	nConnectionTimeout = 30			&& Default 30 sec's
	nAuthenticate = cdoAnonymous
	cUserName = ""
	cPassword = ""
	* Do not use cache for cHtmlBodyUrl
	lURLGetLatestVersion = .T.

	* Optional. Creates your own X-MAILER field in the header
	cXMailer = "VFP CDO 2000 mailer Ver 1.1.100 2010"

	PROTECTED PROCEDURE Init
		This.ClearErrors()
	ENDPROC

	* Send message
	PROCEDURE Send

		IF This.GetErrorCount() > 0
			RETURN This.GetErrorCount()
		ENDIF

		WITH This
			.ClearErrors()
			.oCfg = CREATEOBJECT("CDO.Configuration")
			.oMsg = CREATEOBJECT("CDO.Message")
			.oMsg.Configuration = This.oCfg
		ENDWITH

		* Fill message attributes
		LOCAL lnind, laList[1], loHeader, laDummy[1], lcMailHeader

		IF This.SetConfiguration() > 0
			RETURN This.GetErrorCount()
		ENDIF

		IF EMPTY(This.cFrom)
			This.AddError("ERROR : From is empty.")
		ENDIF
		IF EMPTY(This.cSubject)
			This.AddError("ERROR : Subject is empty.")
		ENDIF

		IF EMPTY(This.cTo) AND EMPTY(This.cCC) AND EMPTY(This.cBCC)
			This.AddError("ERROR : To, CC and BCC are all empty.")
		ENDIF

		IF This.GetErrorCount() > 0
			RETURN This.GetErrorCount()
		ENDIF

		This.SetHeader()

		WITH This.oMsg

			.From     = This.cFrom
			.ReplyTo  = This.cReplyTo

			.To       = This.cTo
			.CC       = This.cCC
			.BCC      = This.cBCC
			.Subject  = This.cSubject

			* Create HTML body from external HTML (file, URL)
			IF NOT EMPTY(This.cHtmlBodyUrl)
				.CreateMHTMLBody(This.cHtmlBodyUrl)
			ENDIF

			* Send HTML body. Creates TextBody as well
			IF NOT EMPTY(This.cHtmlBody)
				.HtmlBody = This.cHtmlBody
			ENDIF

			* Send Text body. Could be different from HtmlBody, if any
			IF NOT EMPTY(This.cTextBody)
				.TextBody = This.cTextBody
			ENDIF

			IF NOT EMPTY(This.cCharset)
				IF NOT EMPTY(.HtmlBody)
					.HtmlBodyPart.Charset = This.cCharset
				ENDIF

				IF NOT EMPTY(.TextBody)
					.TextBodyPart.Charset = This.cCharset
				ENDIF
			ENDIF
			
			* Process attachments
			IF NOT EMPTY(This.cAttachment)
				* Accepts comma or semicolon
				* VFP 7.0 and later
				*FOR lnind=1 TO ALINES(laList, This.cAttachment, [,], [;])
				* VFP 6.0 and later compatible
				FOR lnind=1 TO ALINES(laList, CHRTRAN(This.cAttachment, [,;], CHR(13) + CHR(13)))
					lcAttachment = ALLTRIM(laList[lnind])
					* Ignore empty values
					IF EMPTY(laList[lnind])
						LOOP
					ENDIF

					* Make sure that attachment exists
					IF ADIR(laDummy, lcAttachment) = 0
						This.AddError("ERROR: Attachment not Found - " + lcAttachment)
					ELSE
						* The full path is required.
						IF 	UPPER(lcAttachment) <> UPPER(FULLPATH(lcAttachment))
							lcAttachment = FULLPATH(lcAttachment)
						ENDIF
						.AddAttachment(lcAttachment)
					ENDIF
				ENDFOR
			ENDIF

			IF NOT EMPTY(This.cCharset)
				.BodyPart.Charset = This.cCharset
			ENDIF

			* Priority
			IF NOT EMPTY(This.cPriority)
				lcMailHeader = "urn:schemas:mailheader:"
				.Fields(lcMailHeader + "Priority")   = LOWER(This.cPriority)
				.Fields(lcMailHeader + "Importance") = LOWER(This.cPriority)
				DO CASE
				CASE This.cPriority = "High"
					.Fields(lcMailHeader + "X-Priority") = 1 && 5=Low, 3=Normal, 1=High
				CASE This.cPriority = "Normal"
					.Fields(lcMailHeader + "X-Priority") = 3 && 5=Low, 3=Normal, 1=High
				CASE This.cPriority = "Low"
					.Fields(lcMailHeader + "X-Priority") = 5 && 5=Low, 3=Normal, 1=High
				ENDCASE
				.Fields.Update()
			ENDIF
		ENDWITH

		IF This.GetErrorCount() > 0
			RETURN This.GetErrorCount()
		ENDIF

		This.oMsg.Send()

		RETURN This.GetErrorCount()

	ENDPROC

	* Clear errors collection
	PROCEDURE ClearErrors()
		This.nErrorCount = 0
		DIMENSION This.aErrors[1]
		This.aErrors[1] = Null
		RETURN This.nErrorCount
	ENDPROC

	* Return # of errors in the error collection
	PROCEDURE GetErrorCount
		RETURN This.nErrorCount
	ENDPROC

	* Return error by index
	PROCEDURE GetError
		LPARAMETERS tnErrorno
		IF	tnErrorno <= This.GetErrorCount()
			RETURN This.aErrors[tnErrorno]
		ELSE
			RETURN Null
		ENDIF
	ENDPROC

	* Populate configuration object
	PROTECTED PROCEDURE SetConfiguration

		* Validate supplied configuration values
		IF EMPTY(This.cServer)
			This.AddError("ERROR: SMTP Server isn't specified.")
		ENDIF
		IF NOT INLIST(This.nAuthenticate, cdoAnonymous, cdoBasic)
			This.AddError("ERROR: Invalid Authentication protocol ")
		ENDIF
		IF This.nAuthenticate = cdoBasic ;
				AND (EMPTY(This.cUserName) OR EMPTY(This.cPassword))
			This.AddError("ERROR: User name/Password is required for basic authentication")
		ENDIF

		IF 	This.GetErrorCount() > 0
			RETURN This.GetErrorCount()
		ENDIF

		WITH This.oCfg.Fields

			* Send using SMTP server
			.Item(cdoSendUsingMethod) = cdoSendUsingPort
			.Item(cdoSMTPServer) = This.cServer
			.Item(cdoSMTPServerPort) = This.nServerPort
			.Item(cdoSMTPConnectionTimeout) = This.nConnectionTimeout

			.Item(cdoSMTPAuthenticate) = This.nAuthenticate
			IF This.nAuthenticate = cdoBasic
				.Item(cdoSendUserName) = This.cUserName
				.Item(cdoSendPassword) = This.cPassword
			ENDIF
			.Item(cdoURLGetLatestVersion) = This.lURLGetLatestVersion
			.Item(cdoSMTPUseSSL) = This.lUseSSL

			.Update()
		ENDWITH

		RETURN This.GetErrorCount()

	ENDPROC

	*----------------------------------------------------
	* Add message to the error collection
	PROTECTED PROCEDURE AddError
		LPARAMETERS tcErrorMsg
		This.nErrorCount = This.nErrorCount + 1
		DIMENSION This.aErrors[This.nErrorCount]
		This.aErrors[This.nErrorCount] = tcErrorMsg
		RETURN This.nErrorCount
	ENDPROC

	*----------------------------------------------------
	* Format an error message and add to the error collection
	PROTECTED PROCEDURE AddOneError
		LPARAMETERS tcPrefix, tnError, tcMethod, tnLine
		LOCAL lcErrorMsg, laList[1]
		IF INLIST(tnError, 1427,1429)
			AERROR(laList)
			lcErrorMsg = TRANSFORM(laList[7], "@0") + "  " + laList[3]
		ELSE
			lcErrorMsg = MESSAGE()
		ENDIF
		This.AddError(tcPrefix + ":" + TRANSFORM(tnError) + " # " + ;
			tcMethod + " # " + TRANSFORM(tnLine) + " # " + lcErrorMsg)
		RETURN This.nErrorCount
	ENDPROC

	*----------------------------------------------------
	* Simple Error handler. Adds VFP error to the objects error collection
	PROTECTED PROCEDURE Error
		LPARAMETERS tnError, tcMethod, tnLine
		This.AddOneError("ERROR: ", tnError, tcMethod, tnLine )
		RETURN This.nErrorCount
	ENDPROC

	*-------------------------------------------------------
	* Set mail header fields, if necessary. For now sets X-MAILER, if specified
	PROTECTED PROCEDURE SetHeader
		LOCAL loHeader
		IF NOT EMPTY(This.cXMailer)
			loHeader = This.oMsg.Fields
			WITH loHeader
				.Item(cdoXMailer) =  This.cXMailer
				.Update()
			ENDWITH
		ENDIF
	ENDPROC

	*----------------------------------------------------
	*
	PROTECTED PROCEDURE cPriority_assign(tvVal)
		* Check for incorrect values
		IF INLIST("~" + PROPER(tvVal) + "~", "~High~", "~Normal~", "~Low~") OR EMPTY(tvVal)
			This.cPriority = PROPER(ALLTRIM(tvVal))
		ELSE
			This.AddError("ERROR: Invalid value for cPriority property.")	
		ENDIF
	ENDPROC

ENDDEFINE

I just got an email whose X-Mailer is «X-Mailer: Microsoft CDO for Windows 2000». It has as an attachment a .sgn file, whose content is an XML with one field apparently being a base64-encoded PDF:

<DocumentEnvelope><SignaturePackage><Signature =
xmlns=3D"http://www.w3.org/2000/09/xmldsig#"><SignedInfo><Canonicalizatio=
nMethod Algorithm=3D"http://www.w3.org/TR/2001/REC-xml-c14n-20010315" =
/><SignatureMethod =
Algorithm=3D"http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference =
URI=3D"#SignedDoc"><DigestMethod =
Algorithm=3D"http://www.w3.org/2000/09/xmldsig#sha1" =
/><DigestValue>MFV2XJ9rfjhGCyA948wKB741ChQ=3D</DigestValue></Reference></=
SignedInfo><SignatureValue>aKHfEGfu2p9RdShv1Vv/kqC6gjdymojq0rQA+AU/hPocrr=
VqMQk2wbbJD60jc8QPP0kPIo4vWqB1mVx5Y45HK0LFWxMDkJ2/CN8GcODEum2Mamn3W2j9tKV=
8JfJAexlW47LprDq99W9YwfpXusaEplCOErCRj/2dhnGc4SgZXxw=3D</SignatureValue><=
KeyInfo><KeyValue><RSAKeyValue><Modulus>nz78eiuYN1Jmm5ND8xLLbJ9QTrBpjTMfv=
h4mbmHbBSB7HSHU+7Izp5GCiyDAlmXa3JjqKBRjw2+OpwhsJf+KHPltKFKwOltTN9QJWS4HJm=
H1xqF4VAuwvpp1tlJd1KP5WL/j9YCYigzEfZIAAUC2KiFlAxoR1mwz3alMR4v96h8=3D</Mod=
ulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo><Object =
Id=3D"SignedDoc"><DocumentOriginName =
xmlns=3D"">ecd20f25-95b3-4dc3-b8e6-fc62d23db259</DocumentOriginName><Docu=
mentExtension xmlns=3D"">pdf</DocumentExtension><DocumentCreationDate =
xmlns=3D"">2014-02-27T22:10:27.4320656+02:00</DocumentCreationDate><Docum=
entContent =
xmlns=3D"">JVBERi0xLjQNJeLjz9MNCjMgMCBvYmoNPDwvQ291bnQgMS9LaWRzWzQgMCBSXS=
9QYXJlbnQgMiAwIFIgDS9UeXBlL1BhZ2VzPj4NZW5kb2JqDTQgMCBvYmoNPDwvQXJ0Qm94WzA=

(… etc. etc. …)

P9fdsc3jL4yg7at7G488BKcqQbpnZDkhXFsfhc/VIuPexfElgnf2oagaf/QjiZHy+ganiZcAH=
dFFFrN6xYK5n0JL5g330NKzD5CHBS8X1civ8VUAKdWjgI8pm1rFsm4v20SwIp/81OH1w=3D=3D=
</CertBase64></Certificate></SignaturePackage></DocumentEnvelope>

If I copy out just the DocumentContent part, and base64-decode it, I see a PDF 1.3 header, but some decoders choke on it, and anyway, I can’t get a working PDF from that thing. So:

  • How can I manually extract the PDF file from there?
  • Is there a standalone tool for extracting files from such mail messages, or from .sgn files?
  • Is there a Thunderbird extension which handles these, and presents the PDF as a regular attachment?

Notes:

  • The file was sent automatically by the Israel courts’ ‘Net Ha-Mishpat’ platform. I can contact the courts but they have no technically-literate people, and I can’t contact the software contractor they used.
  • I know of people who have, in the past, managed to extract decoded files from these .sgn’s, I just don’t know how exactly.

asked Feb 27, 2014 at 21:13

einpoklum's user avatar

einpoklumeinpoklum

8,07318 gold badges72 silver badges138 bronze badges

I got one of those documents myself today.

Since explaining what is wrong to the tech support people seemed likely to take more time than attempting to extract it myself, I created a small python script to extract and decode the pdf document that was embedded in the sig file.

That is, assuming that there is a single attached pdf file and the sig file format is the same as mine.

I hope that someone would find it useful.

import base64
import xml.etree.ElementTree as ET
import sys


def decode(infile, outfile):
    tree = ET.parse(infile)
    xmlns = '{http://www.w3.org/2000/09/xmldsig#}'
    b64 = tree.find("./SignaturePackage/{0}Signature/{0}Object/DocumentContent".format(xmlns)).text
    txt = base64.b64decode(b64)

    with open(outfile, 'bw+') as f:
        f.write(txt)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print('usage: python unpack.py <input_filename>')
        exit(1)
    infile = sys.argv[1]
    outfile = 'out.pdf'
    decode(infile, outfile)
    print('Done. Result saved to {0}'.format(outfile))

I created a gist for this script.

You need to have python 3.x installed, put the sig file and the python script in the same folder (or provide the file path to the script) and execute it like so:

python unpack.py <sig_filename>

This will create a file named out.pdf in the same folder.

answered May 12, 2015 at 10:20

MasterAM's user avatar

5

Here’s a rudimentary script you can use on Unix-like systems (and probably on Windows too with a little modification) to extract the PDF file out of the document envelope; I call it sgn2pdf (since the doc envelope file have an sgn extension). Its command-line interface is

sgn2pdf [INPUT_FILENAME] [OUTPUT_FILENAME]

i.e. if you add a first argument it will read from that file rather than from the standard input; and if you add a second argument it will redirect the output into the second file specified.

Source:

#!/bin/bash
#
# Extract a PDF file from an Israeli courts' .sgn PDF document envelope

exec 3<&0 # tie (new) file descriptor 3 to what is currently the standard input
exec 4>&1 # tie (new) file descriptor 4 to what is currently the standard output

if [[ $# > 0 ]]; then
    exec 3<$1 
    shift
fi
if [[ $# > 0 ]]; then
    exec 4>$1
    shift
fi
exec <&3 >&4
sed -r 's/^.*<DocumentContent[^>]*>//; s/</Document.*$//;' | base64 -d -i >&4

The base64 decoder is part of the GNU coreutils package and should be available on any Linux distribution.

answered Oct 30, 2016 at 8:10

einpoklum's user avatar

einpoklumeinpoklum

8,07318 gold badges72 silver badges138 bronze badges

The use of CDO 200 and the document envelope indicate that the email was likely sent automatically or programmatically, i.e. via a script, out of Access, or in some other way via SMTP and a CDO-compliant program (not a normal mail client).

The SGN file is unlikely to be a true SGN file, which is a «Sierra Print Artist» file; it seems more likely that someone has used the extension manually for a signature file.

I do not believe that this file was intended to be the sort of attachment that you would be expected to open. It seems far more likely that the file you’re seeing is included with the email as a way for the sender to show it as «signed» when it is automatically generated. Because the PDF is embedded within the XML file, there is likely no extension which would automatically decode the section of the attachment that you believe to be a PDF. You could try copying the entire section and then decoding it, and saving the decoded text with a unicode-compliant text editor, then see if that opens as a readable PDF.

But I think you are wasting your time and this attachment is along the lines of what you’d see if someone included a vCard which contained an image when they sent you email out of some program via CDO. That is, it’s not intended to be decoded, because if you could do that, then perhaps you could falsify the signature of the sender.

Have you tried contacting the sender to find out whether the attachment has any meaning? It seems fairly obvious to me that it is just intended to be a qualifying signature file. The header tells you that the algorithm used to generate the signature is at
http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#rsa-sha1 — that alone should tell you that it’s not a file that you are meant to open as such.

answered Feb 28, 2014 at 6:08

Debra's user avatar

DebraDebra

4,2501 gold badge17 silver badges24 bronze badges

3

Probably too late, but if you got this file from the Israeli court system (נט המשפט), then here they give a link (this link) to a windows program that opens it.

answered Nov 29, 2015 at 22:49

yohbs's user avatar

yohbsyohbs

1011 bronze badge

2

Создаю письмо через CDO.Message. Отсылаю его сам себе.
Значимые куски скрипта:

Письмо успешно уходит, мне приходит уведомление о доставке письма, но не приходит уведомление о прочтении. Заголовок письма формируется следующий:

Received: from KEMIT03 (KEM-ITxx [10.xx.xx.12]) by exchange.kemerovo.goracadem.ru with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2653.13)
id LTWFHF5V; Thu, 26 May 2005 10:31:42 +0700
Return-Receipt-To: <koltsov@kemerovo.goracadem.ru>
From: <koltsov@kemerovo.goracadem.ru>
To: <koltsov@kemerovo.goracadem.ru>
Subject: This is a CDO test message
Date: Thu, 26 May 2005 10:29:38 +0800
Message-ID: <000001c5619a$c3761200$0c1e140a@KEMIT03>
MIME-Version: 1.0
Content-Type: text/plain;
charset=»koi8-r»
Content-Transfer-Encoding: 7bit
X-Mailer: Microsoft CDO for Windows 2000
Disposition-Notification-To: <koltsov@kemerovo.goracadem.ru>
Thread-Index: AcVhmsNxa14gLdRhTbGiPWJZ/qqZZg==
Content-Class: urn:content-classes:message
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409

Формирую письмо через MS Outlook (так же самому себе). Успешно приходят оба уведомления: и о доставке письма и о прочтении. Заголовок письма Outlook формирует вот такой:

Значимых различий в заголовках я не вижу в упор.

Причем в свойствах письма(смотрю их в Outlook: Файл-Свойства), сформированного Outlook, указано следующее:

Требуется уведомление о прочтении: Да
Требуется уведомление о доставке: Да

Свойства же письма, сформированнго скриптом, показываются вот такие:

Требуется уведомление о прочтении: Нет
Требуется уведомление о доставке: Да

Два взаимосвязанных вопроса.
Первый: как же мне скриптом формировать письмо, чтобы приходило еще и уведомление о прочтении.
Второй: что такого знает Outlook, чего не знаю я? То есть по каким признакам он определяет, что в «его» письме все уведомления включены, а в «скриптовом» уведомление о прочтении не включено?

Понравилась статья? Поделить с друзьями:
  • X live wallpaper скачать для windows
  • X files the game проблема с шрифтом на windows 10
  • X cop плеер скачать для windows 10
  • X com ufo defense скачать торрент windows 10
  • X com ufo defense для windows