none
Unable to copy/add contact in programatically created pst file through vsto RRS feed

  • Question

  • Hi,

    this is in continuation with the following thread,

    http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/1eb7faa0-08c7-47bf-a54b-ae86da23c8be/

    I developed outlook addin for 2007 and 2010. using vsto,C#, right now executing code at OL2007.

    I wrote the following code which is creating pst file by using AddStore method, and then I tried to copy/add contacts from default personal folder to it, but I'm getting an exception at line marked with //##  that - "Could not complete the operation, one or more parameter values are not valid ".

    Well I'm able to read the contact properties fine, as message box is showing full name fine. these contacts have some user defined properties also, but I tried with the newly created contact at outlook, but same error. Could you correct me where I'm doing mistake or how I can I fix it.

    The pst file is creating fine and I'm able to import it at outlook by using import/export wizard, but obviously as no contacts are added into it, so no results at outlook.

    here is code

    private void BackupContacts()
            {
               Outlook.Application olApp = new Outlook.Application();
                Outlook.NameSpace nameSpace = olApp.GetNamespace("MAPI");

                Outlook.MAPIFolder olBackup;
                Outlook.MAPIFolder olBackContactsFolder;
                Outlook.Items collContItems;
                Outlook.Items collBackContItems;
                Object objSrc; //contact folder items can be various types
                Object oCopy;


                nameSpace.AddStore(@"C:\Users\Mehnaz\AppData\Local\Temp\123.PST");
                olBackup = nameSpace.Folders[nameSpace.Folders.Count];
                MAPIFolder contactsFolder = Application.Session.GetDefaultFolder(OlDefaultFolders.olFolderContacts);

                olBackContactsFolder = null;
                //olBackContactsFolder = olBackup.Folders["Contacts"];
                try
                {
                    olBackContactsFolder = olBackup.Folders["Contacts"];
                }
                catch
                {
                    try
                    {
                        olBackContactsFolder=olBackup.Folders.Add("Contacts",OlDefaultFolders.olFolderContacts);
                    }
                    catch (System.Exception es)
                    {
                        MessageBox.Show(es.Message);
                    }
                }

               

                collContItems = contactsFolder.Items;
                collBackContItems = olBackContactsFolder.Items;
                foreach(Outlook.ContactItem contact in collContItems)
                {
                    try
                    {
                        MessageBox.Show(contact.FullName.ToString());
                        collBackContItems.Add(contact); //##
                    }
                    catch (System.Exception e12)
                    {
                        MessageBox.Show(e12.Message);
                    }
                }
               

        

            }

    Note: before posting here, I tried much and searched net, but didn't find solution, so would be thankful to you, if you can help me asap.

     


    Mehnaz Anwar
    Thursday, April 14, 2011 3:33 AM

Answers

  • Hello Mehnaz,

    you can use:

    Outlook.Application olApp = Globals.ThisAddIn.Application;
    Outlook.NameSpace nameSpace = olApp.Session;

     

    instead.

    What Outlook - Version are you using? 2007?

    The backUpStore.Session.GetDefaultFolder is the same as nameSpace.GetDefaultFolder and will return your default contactfolder.

    So I created a Method to create the SubFolder and for me it's working fine now:

    private Outlook.MAPIFolder FindOrCreateFolder(Outlook.MAPIFolder parentFolder, string foldername, Outlook.OlDefaultFolders folderType) {
    
      foreach (Outlook.MAPIFolder folder in parentFolder.Folders) {
        if (folder.Name == foldername) {
    
          // Folder found
          return folder;
        }
      }
    
      // not found, create a new
      return parentFolder.Folders.Add(foldername, folderType);
    }
    
    
    
    private void BackupContacts() {
    
      // Don't do this in an AddIn !!!!!
      // Use Globals.ThisAddIn.Application and the existing Session instead
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      Outlook.Application olApp = new Outlook.Application();
      //Outlook.NameSpace nameSpace = olApp.GetNamespace("MAPI");
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
      Outlook.Store backUpStore = null;
      Outlook.MAPIFolder contactsFolder;
      Outlook.MAPIFolder olBackContactsFolder;
      Outlook.Items collContItems;
      Outlook.Items collBackContItems;
      Object objSrc; //contact folder items can be various types 
      Outlook.ContactItem oCopy;
    
      string storePath = @"C:\Temp\123.PST";
    
      try {
    
    
        // Add a new store
        olApp.Session.AddStore(storePath);
    
        // Get the Store
        foreach (Outlook.Store store in olApp.Session.Stores) {
          if (store.FilePath == storePath) {
            backUpStore = store;
            break;
          }
        }
    
        if (backUpStore == null) {
          throw new ApplicationException("Outlook Store at " + storePath + " not found");
        }
    
        // Your default contactfolder
        contactsFolder = olApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
    
        // Get the Backup Default Folder
        // OL2010: olBackContactsFolder = backUpStore.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
    
        olBackContactsFolder = FindOrCreateFolder(backUpStore.GetRootFolder(), contactsFolder.Name, Outlook.OlDefaultFolders.olFolderContacts);
    
        collContItems = contactsFolder.Items;
        collBackContItems = olBackContactsFolder.Items;
        foreach (Outlook.ContactItem contact in collContItems) {
          try {
            //MessageBox.Show(contact.FullName);
            // collBackContItems.Add(contact); //##
            Outlook.ContactItem contactCopy = contact.Copy();
            contactCopy.Move(olBackContactsFolder);
            contactCopy = null;
          } catch (System.Exception e12) {
            MessageBox.Show(e12.Message);
          }
        }
    
        // detach pst
        olApp.Session.RemoveStore(backUpStore.GetRootFolder());
    
      } catch (System.Exception ex) {
            
        // Some Error Logging
    
      } finally {
        // Cleanup
        collBackContItems = null;
        collContItems = null;
        olBackContactsFolder = null;
        contactsFolder = null;
        backUpStore = null;
        //nameSpace = null;
        olApp = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
      }
    }
    


    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    Friday, April 15, 2011 5:45 AM
    Answerer
  • Hi Mehnaz,

     

    you need to set the folder and the store objects to null and then

    GC.Collect()

    GC.WaitForPendingFinalizers();

    this should help I think.

    (Release the COM Objects safely)


    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    Monday, April 18, 2011 8:30 PM
    Answerer

All replies

  • Hello Mehnaz,

    something like that:

    private void BackupContacts() {
    
      // Don't do this in an AddIn !!!!!
      // Use Globals.ThisAddIn.Application and the existing Session instead
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      Outlook.Application olApp = new Outlook.Application();
      Outlook.NameSpace nameSpace = olApp.GetNamespace("MAPI");
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
      Outlook.Store backUpStore = null;
      Outlook.MAPIFolder contactsFolder;
      Outlook.MAPIFolder olBackContactsFolder;
      Outlook.Items collContItems;
      Outlook.Items collBackContItems;
      Object objSrc; //contact folder items can be various types 
      Outlook.ContactItem oCopy;
    
      string storePath = @"C:\Temp\123.PST";
    
      try {
    
    
        // Add a new store
        nameSpace.AddStore(storePath);
    
        // Get the Store
        foreach (Outlook.Store store in nameSpace.Stores) {
          if (store.FilePath == storePath) {
            backUpStore = store;
            break;
          }
        }
    
        if (backUpStore == null) {
          throw new ApplicationException("Outlook Store at " + storePath + " not found");
        }
    
        // Your default contactfolder
        contactsFolder = olApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
    
        // Get the Backup Default Folder
        olBackContactsFolder = backUpStore.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
    
        collContItems = contactsFolder.Items;
        collBackContItems = olBackContactsFolder.Items;
        foreach (Outlook.ContactItem contact in collContItems) {
          try {
            MessageBox.Show(contact.FullName);
            // collBackContItems.Add(contact); //##
            Outlook.ContactItem contactCopy = contact.Copy();
            contactCopy.Move(olBackContactsFolder);
            contactCopy = null;
          } catch (System.Exception e12) {
            MessageBox.Show(e12.Message);
          }
        }
    
        // detach pst
        nameSpace.RemoveStore(backUpStore.GetRootFolder());
    
      } catch (System.Exception ex) {
            
        // Some Error Logging
    
      } finally {
        // Cleanup
        collBackContItems = null;
        collContItems = null;
        olBackContactsFolder = null;
        contactsFolder = null;
        backUpStore = null;
        nameSpace = null;
        olApp = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
      }
    }
    
    Greets - Helmut
    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    Thursday, April 14, 2011 6:19 AM
    Answerer
  • Hi Helmut,

     

    First of all , thankful to you that you provided the updated code, well this is giving problem.

    I used

    Outlook.Application olApp = Globals.ThisAddIn.Application;
    Outlook.NameSpace nameSpace = olApp.GetNamespace("MAPI");

    instead of

     Outlook.Application olApp = new Outlook.Application();
    Outlook.NameSpace nameSpace = olApp.GetNamespace("MAPI");

    and tried with original lines, does not matter.

    ---------------------

    this line

    // Get the Backup Default Folder
    olBackContactsFolder = backUpStore.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);

    was giving error at compilation that backupStore has no such method of GetDefaultFolder so I changed into following

    olBackContactsFolder = backUpStore.Session.GetDefaultFolder;

    compiled successfully, but when this process executes, it copies the contact fine, so in same contacts folder duplicate contact created, but then giving the exception that unable to move the item.
    and then stuck in foreach loop.

    I changed the above line to

    olBackContactsFolder = backUpStore.GetRootFolder();

    then it creates duplicate, no exception, but no move I think, as duplicate contacts created then stuck in loop.

    any help,

    Thanks
    --Mehnaz





     

     

     


    Mehnaz Anwar
    Friday, April 15, 2011 3:54 AM
  • Hello Mehnaz,

    you can use:

    Outlook.Application olApp = Globals.ThisAddIn.Application;
    Outlook.NameSpace nameSpace = olApp.Session;

     

    instead.

    What Outlook - Version are you using? 2007?

    The backUpStore.Session.GetDefaultFolder is the same as nameSpace.GetDefaultFolder and will return your default contactfolder.

    So I created a Method to create the SubFolder and for me it's working fine now:

    private Outlook.MAPIFolder FindOrCreateFolder(Outlook.MAPIFolder parentFolder, string foldername, Outlook.OlDefaultFolders folderType) {
    
      foreach (Outlook.MAPIFolder folder in parentFolder.Folders) {
        if (folder.Name == foldername) {
    
          // Folder found
          return folder;
        }
      }
    
      // not found, create a new
      return parentFolder.Folders.Add(foldername, folderType);
    }
    
    
    
    private void BackupContacts() {
    
      // Don't do this in an AddIn !!!!!
      // Use Globals.ThisAddIn.Application and the existing Session instead
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      Outlook.Application olApp = new Outlook.Application();
      //Outlook.NameSpace nameSpace = olApp.GetNamespace("MAPI");
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
      Outlook.Store backUpStore = null;
      Outlook.MAPIFolder contactsFolder;
      Outlook.MAPIFolder olBackContactsFolder;
      Outlook.Items collContItems;
      Outlook.Items collBackContItems;
      Object objSrc; //contact folder items can be various types 
      Outlook.ContactItem oCopy;
    
      string storePath = @"C:\Temp\123.PST";
    
      try {
    
    
        // Add a new store
        olApp.Session.AddStore(storePath);
    
        // Get the Store
        foreach (Outlook.Store store in olApp.Session.Stores) {
          if (store.FilePath == storePath) {
            backUpStore = store;
            break;
          }
        }
    
        if (backUpStore == null) {
          throw new ApplicationException("Outlook Store at " + storePath + " not found");
        }
    
        // Your default contactfolder
        contactsFolder = olApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
    
        // Get the Backup Default Folder
        // OL2010: olBackContactsFolder = backUpStore.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
    
        olBackContactsFolder = FindOrCreateFolder(backUpStore.GetRootFolder(), contactsFolder.Name, Outlook.OlDefaultFolders.olFolderContacts);
    
        collContItems = contactsFolder.Items;
        collBackContItems = olBackContactsFolder.Items;
        foreach (Outlook.ContactItem contact in collContItems) {
          try {
            //MessageBox.Show(contact.FullName);
            // collBackContItems.Add(contact); //##
            Outlook.ContactItem contactCopy = contact.Copy();
            contactCopy.Move(olBackContactsFolder);
            contactCopy = null;
          } catch (System.Exception e12) {
            MessageBox.Show(e12.Message);
          }
        }
    
        // detach pst
        olApp.Session.RemoveStore(backUpStore.GetRootFolder());
    
      } catch (System.Exception ex) {
            
        // Some Error Logging
    
      } finally {
        // Cleanup
        collBackContItems = null;
        collContItems = null;
        olBackContactsFolder = null;
        contactsFolder = null;
        backUpStore = null;
        //nameSpace = null;
        olApp = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
      }
    }
    


    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    Friday, April 15, 2011 5:45 AM
    Answerer
  • HI Helmut,

    You helped me great, very very thankful to you. Now code is working absolutely fine. well just little modification/addition I require that, when the file is created for saving contacts then it can't be open in the same session for restoring contacts from it by outlook import/export contacts wizard. the wizard message box displays "The file can't be opened"

    I always need to close the outlook or stop debugging(then it closed the outlook) and again start outlook to use same file in outlook wizard.

    Though following line , I thought , will release the file also.

    // detach pst
    olApp.Session.RemoveStore(backUpStore.GetRootFolder());

    Any idea..

     

    Thanks

    --Mehnaz


    Mehnaz Anwar
    Monday, April 18, 2011 5:13 AM
  • Hi Mehnaz,

     

    you need to set the folder and the store objects to null and then

    GC.Collect()

    GC.WaitForPendingFinalizers();

    this should help I think.

    (Release the COM Objects safely)


    Helmut Obertanner [http://www.x4u.de] [http://www.outlooksharp.de]
    Monday, April 18, 2011 8:30 PM
    Answerer
  • Hi Helmit,

     

    By the way, in the finally block, you did already set these store,folders to null. what other thing I set to null here.

    well just for checking in the finally block, I put the following code, which is confirming that file is detached successfully, but still file is in use somewhere in outlook memory, because neither I can use it in import/export wizard  nor I can delete or move the file somewhere else in the disk outside of outlook, until I close the outlook. If I go to delete the file, it says, the operation can't be completed as the file is open in another program.

    finally
          {
            // Cleanup
            collBackContItems = null;
            collContItems = null;
            olBackContactsFolder = null;
            contactsFolder = null;
            backUpStore = null;
            // nameSpace = null;
            //olApp = null;
            
            GC.Collect();
            GC.WaitForPendingFinalizers();
    
            // Get the Store
            foreach (Outlook.Store store in olApp.Session.Stores)
            {
              if (store.FilePath == storePath)
              {
                backUpStore = store;
                break;
              }
            }
    
            if (backUpStore == null)
            {
              throw new ApplicationException("Outlook Store at " + storePath + " not found");
            }
          } 
    

     

    Thanks

    --Mehnaz


    Mehnaz Anwar
    Tuesday, April 19, 2011 6:08 AM
  • Hey Helmut

    I could give you a big bear hug right now. I was about to pull my hair out or bang my head into a wall somewhere until I saw this by you 

        GC.Collect();
        GC.WaitForPendingFinalizers();

    I always knew I was getting random failures because of memory management issues but had no clue how to get around them. Your help has rekindled my dwindling passion for my hobby project. A big thanks again. Keep up the good work :)

     

     

    Sunday, June 5, 2011 10:38 PM