public void Download(string localPath) { byte[] metadataHash = HashAttachmentMetadata(Name, Comment, DisplayName, Length); if (null == CQSession) { throw new InvalidOperationException("CQSession == NULL"); } // [teyang] TODO: validation on localPath if (File.Exists(localPath)) { File.Delete(localPath); } OAdEntity aRecord = CQWrapper.GetEntity(CQSession, EntityDefName, EntityDispName); OAdAttachmentFields aAllAttFields = CQWrapper.GetAttachmentFields(aRecord); bool attachmentFound = false; for (int attFieldsIndex = 0; attFieldsIndex < CQWrapper.AttachmentsFieldsCount(aAllAttFields); attFieldsIndex++) { object ob = (object)attFieldsIndex; OAdAttachmentField aAttField = CQWrapper.AttachmentsFieldsItem(aAllAttFields, ref ob); string fieldName = CQWrapper.GetAttachmentFieldName(aAttField); if (!CQStringComparer.FieldName.Equals(fieldName, this.FieldName)) { // not the hosting attachment field, try next one continue; } // attachment field is found, now look for the attachment OAdAttachments aAttachments = CQWrapper.GetAttachments(aAttField); OAdAttachment aAttachment = null; for (int attachmentIndex = 0; attachmentIndex < CQWrapper.AttachmentsCount(aAttachments); attachmentIndex++) { object obIndex = (object)attachmentIndex; aAttachment = CQWrapper.AttachmentsItem(aAttachments, ref obIndex); string name; string comment; string dispName; int fileSize; CQWrapper.GetAttachmentMetadata(aAttachment, out name, out comment, out dispName, out fileSize); byte[] hash = HashAttachmentMetadata(name, comment, dispName, (long)fileSize); if (HashProducer.CompareMD5(metadataHash, hash) == 0) { attachmentFound = true; break; } } if (attachmentFound) { Debug.Assert(null != aAttachment, "null == aAttachment"); CQWrapper.LoadAttachment(aAttachment, localPath); } // we've checked the host att field already, no need to proceed break; } if (!attachmentFound) { // [teyang] TODO: typed exception, AttachmentNotFound conflict handling throw new Exception(string.Format("attachment '{0}' is not found", Name)); } }