Save mail as msg without attachments

Add-in Express™ Support Service
That's what is more important than anything else

Save mail as msg without attachments
 
Spiros Nikolopoulos


Guest


I' trying to save a mail as msg without the attachments.
I did a forum search but I still can't find solution (using delphi XE2) for the message to discard changes when outlook closes using :


if IMAil.Attachments.Count > 0 then
     begin
       while IMail.Attachments.Count > 0 do
              IMail.Attachments.Remove(1);
     end;

    IMail.SaveAs(_Temp+'Attachments'+CreateFileName(Subject) + '.msg' ,olMSG);
    IMail.Close(olDiscard);


I also get a message (you have to be online to perform this operation ...) when I'm trying to save the mail after setting its category

I'm connected to an IMAP server
Thanks
Posted 26 Jul, 2012 04:27:59 Top
Andrei Smolin


Add-in Express team


Posts: 18830
Joined: 2006-05-11
Hi Spiros,

Is the email open in an inspector window or selected in the explorer window?

Spiros Nikolopoulos writes:
I also get a message (you have to be online to perform this operation ...) when I'm trying to save the mail after setting its category


Please try to do the same in the Outlook UI. Do you get the same message?


Andrei Smolin
Add-in Express Team Leader
Posted 26 Jul, 2012 08:20:23 Top
Spiros Nikolopoulos


Guest


The email is selected in the explorer window and I don't get the same message in the Outlook UI when I save it as msg or as txt
Thanks
Posted 26 Jul, 2012 08:44:03 Top
Andrei Smolin


Add-in Express team


Posts: 18830
Joined: 2006-05-11
Hi Spiros,

The intendedly code below works fine in Outlook 2010 32bit (all updates) with my Gmail IMAP folder.

procedure TAddInModule.adxRibbonTab1Controls0Controls0Click(Sender: TObject;
  const RibbonControl: IRibbonControl);
var
  item: IDispatch;
  IMail: MailItem;
  sel: Selection;
begin
  OutputDebugString('0');
  try
    sel := OutlookApp.ActiveExplorer.Selection;
  except
  end;
  if sel <> nil then begin
    item := sel.Item(1);
    OutputDebugString('1');
    item.QueryInterface(IID__MailItem, IMail);
    if IMail <> nil then begin
      OutputDebugString('2');
      if IMAil.Attachments.Count > 0 then
         begin
           OutputDebugString('3');
           while IMail.Attachments.Count > 0 do
            IMail.Attachments.Remove(1);
         end;

      OutputDebugString('4');
      IMail.SaveAs('d:'+ 'SaveMailWithNoAttachments.msg' ,olMSG);
      OutputDebugString('5');
      IMail.Close(olDiscard);
      OutputDebugString('6');
    end;
  end;
end;


If it fails in your Outlook, try to turn the Reading Pane off. BTW, what Outlook version (and service pack, please) are you using?


Andrei Smolin
Add-in Express Team Leader
Posted 26 Jul, 2012 11:45:44 Top
Spiros Nikolopoulos


Guest


Hi Andrei,
With the Reading Pane off I get the same error.
The error :

"The connection to the server is unavailable outlook must be online or connected to complete this action"

cames later after the Imail.Close(olDiscard);

when I save the mail after setting category like :


 if (Trim(arcCategory) <> '') then
            begin
              if Trim(MailItem(SelectedItems[mlno]).Categories) = '' then
                MailItem(SelectedItems[mlno]).Categories := arcCategory
              else
                MailItem(SelectedItems[mlno]).Categories :=
                  MailItem(SelectedItems[mlno]).Categories + ';' + arcCategory;
              MailItem(SelectedItems[mlno]).Save; <-- *** Error *** 
            end;



The dev env includes : Outlook 2010 ver 14.0.6112.5000 (32-bit) hmailserver and imap test

with pop accounts works as expected.

Thanks
Posted 26 Jul, 2012 18:06:13 Top
Andrei Smolin


Add-in Express team


Posts: 18830
Joined: 2006-05-11
Hi Spiros,

That is, you close the item and then use it? I think this is incorrect. You can try getting the item anew if you need to modify it after you call Imail.Close(olDiscard).

procedure TAddInModule.adxRibbonTab1Controls0Controls0Click(Sender: TObject;
  const RibbonControl: IRibbonControl);
var
  item: IDispatch;
  IMail: MailItem;
  sel: Selection;
  flag: boolean;
begin
  flag := false;
  OutputDebugString('0');
  try
    sel := OutlookApp.ActiveExplorer.Selection;
  except
  end;
  if sel <> nil then begin
    item := sel.Item(1);
    OutputDebugString('1');
    item.QueryInterface(IID__MailItem, IMail);
    if IMail <> nil then begin
      OutputDebugString('2');
      if IMAil.Attachments.Count > 0 then
         begin
           OutputDebugString('3');
           while IMail.Attachments.Count > 0 do
            IMail.Attachments.Remove(1);
         end;

      OutputDebugString('4');
      IMail.SaveAs('d:'+ 'SaveMailWithNoAttachments.msg' ,olMSG);
      OutputDebugString('5');
      IMail.Close(olDiscard);
      OutputDebugString('6');
      flag := true;
      IMail := nil;
      item := nil;
    end;
    if flag then begin
      item := sel.Item(1);
      OutputDebugString('7');
      item.QueryInterface(IID__MailItem, IMail);
      if IMail <> nil then begin
        OutputDebugString('8');
        IMail.Categories := IMail.Categories + ';MyCategory';
        OutputDebugString('9');
        IMail.Save;
      end;
    end;
  end;
end;



Andrei Smolin
Add-in Express Team Leader
Posted 30 Jul, 2012 07:21:24 Top
Spiros Nikolopoulos


Guest


Hi Andrei,

When I integrate your code in my application after the IMail.save the mail loose it's attachments.
before IMail.save when I perform an lMail.Saved I always get false although I did the IMail.Close(olDiscard)
do I have to release com objects after IMail.Close(olDiscard) ?
How to do this in Delphi ? (There is no ReleaseComObjects)

Thanks for you help
Posted 16 Aug, 2012 09:38:25 Top
Dmitry Kostochko


Add-in Express team


Posts: 2875
Joined: 2004-04-05
Hi Spiros,

do I have to release com objects after IMail.Close(olDiscard) ? How to do this in Delphi ? (There is no ReleaseComObjects)


In Delphi, setting an interface variable to nil decreases the interface counter, i.e. releases a com object.

As to your task, I can suggest creating a copy of the mail message. Then you can remove attachments from the copied email, save it to disk and delete it in Outlook using the IMail.Delete() method. What do you think?
Posted 16 Aug, 2012 10:46:32 Top
Spiros Nikolopoulos


Guest


Dmitry,
Thanks for your reply

So I did :


       tmail := (iMail.Copy) as MailItem;

       while tMail.Attachments.Count > 0 do
             tMail.Attachments.Remove(1);
       tMail.SaveAs(_Temp+'Attachments'+CreateFileName(Subject) + '.msg' ,olMSG);
       tMail.Delete;


But the copied mail remains in explorer.
The rest works as expected. Your solution looks good
Posted 16 Aug, 2012 12:32:44 Top
Dmitry Kostochko


Add-in Express team


Posts: 2875
Joined: 2004-04-05
Hi Spiros,

Could you please specify in which Outlook folder the copied email remains? Is it the Deleted Items folder?
Posted 17 Aug, 2012 03:38:15 Top