Store.GetdefaultFolder is creating folders with weird names

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

Store.GetdefaultFolder is creating folders with weird names
 
Subscribe
Tim Smet




Posts: 16
Joined: 2015-10-06
Hi,

I'm currently seeing a similar issue as in this topic:
https://www.add-in-express.com/forum/read.php?FID=5&TID=14523&MID=74404#message74404

At startup of our vcl addin express addon in latest outlook 2016 version we loop over all the stores and call to record their names


OleFolder := OleStore.GetDefaultFolder(olFolderDrafts);
OleFolder := OleStore.GetDefaultFolder(olFolderOutbox);
OleFolder := OleStore.GetDefaultFolder(olFolderSentMail);


With one client these function calls are creating such folders in a certain pst file:
User added an image

the whole part of our code that gets executed is listed below, we disabled / unloaded antivirus and we disabled all other add-ins except our own with the client yet these folders are still created eacht time after a call to OleStore.GetDefaultFolder

If i create a new test pst file on my (dev) pc's outlook 2016 only these folders exist:
User added an image

as soon as i restart outlook it has created a concepts folder when calling "OleStore.GetDefaultFolder(olFolderDrafts)" and for the other 2 it produces a few exceptions like "The operation has failed" when calling that code but no such folders as with the client appear.
User added an image

With the client no exception occur but outlook does create those new folders each time with a weird name depending on which folder i request.

I can't seem to similate this behaviour with pst files.

Also is there a way to know before calling OleStore.GetDefaultFolder that the folder actually exists ? because calling that function outlook seems to try to create the folders and it's that what i guess is failing in some weird way with the client without producing exceptions (like it does with me)

i was unaware that OleStore.GetDefaultFolder tries to create the folders if they don't exist, is there a way to prevent this from happening ?

also https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/store-getdefaultfolder-method-outlook does not mention calling OleStore.GetDefaultFolder on a pst file that outlook tries to create these folders if they don't exist

my guess is the folder creation did not work correctly with the client but it did create a certain folder (with wrong) name on each start up / each time we call that function

The full procedure:

procedure TAddInModule.SetTrackSentItemsFolder(const value: boolean);
var
  OleSession, OleStore, OleFolder, OleItems: OleVariant;
  Teller, iIndex: Integer;
  TmpItems: _Items;
  bFolderSentMailOk: Boolean;
begin
  try
    if DebugTraceMode then DebugLog.Log('Start: TAddInModule.SetTrackSentItemsFolder(' + BoolToStr(value, true) + ')');
    if Length(FItemsArray) > 0 then
    begin
      if not Value then
      begin
        for Teller := 0 to High(FItemsArray) do
        begin
          FItemsArray[Teller].Disconnect;
          FItemsArray[Teller].Free;
          FItemsArray[Teller] := nil;
        end;
        SetLength(FItemsArray, 0);
      end;
    end
    else
    if Value then
    begin
      //Meerdere accounts enkel vanaf 2007 afin het object dat je daarvoor nodig hebt toch
      //dat wil niet zeggen dat dit ook al mogelijk was in 2007
      if GetOutlookVersion >= 12.0 then
      begin
        OleSession := OleVariant(Outlookapp.Session);
        for Teller := 1 to OleSession.Stores.Count do
        begin
          OleStore := OleSession.Stores.Item(Teller);
          ShowMessage(OleStore.displayname);
          //DW  donderdag 17/08/2017 17:18:46: DW
          //    vraag drafts foldernames op voor latere controles
          OleFolder := Unassigned;
          try
            //DW  donderdag 17/08/2017 17:07:08: DW
            //    kan fouten geven bij sommige stores dat de bewerking mislukt is bvb
            //    vandaar try except
            OleFolder := OleStore.GetDefaultFolder(olFolderDrafts);
            if FOutlookSentFolderNames.IndexOf(OleFolder.Name) = -1 then
              FOutlookSentFolderNames.add(OleFolder.Name);
            OleFolder := Unassigned;
          except on E: SysUtils.Exception do
            begin
              ShowMessage(E.Message);
            end;
          end;

          //DW  donderdag 17/08/2017 17:18:46: DW
          //    vraag Outbox foldernames op voor latere controles
          OleFolder := Unassigned;
          try
            //DW  donderdag 17/08/2017 17:07:08: DW
            //    kan fouten geven bij sommige stores dat de bewerking mislukt is bvb
            //    vandaar try except
            OleFolder := OleStore.GetDefaultFolder(olFolderOutbox);
            if FOutlookOutboxFolderNames.IndexOf(OleFolder.Name) = -1 then
              FOutlookOutboxFolderNames.add(OleFolder.Name);
            OleFolder := Unassigned;
          except on E: SysUtils.Exception do
            begin
              ShowMessage(E.Message);
            end;
          end;


          bFolderSentMailOk := True;
          OleFolder := Unassigned;
          try
            OleFolder := OleStore.GetDefaultFolder(olFolderSentMail);
            //DW  donderdag 17/08/2017 17:37:26: DW
            //    sent ook toevoegen aan lijst van namen
            if FOutlookSentFolderNames.IndexOf(OleFolder.Name) = -1 then
              FOutlookSentFolderNames.add(OleFolder.Name);
          except on E: SysUtils.Exception do
            begin
              bFolderSentMailOk := False;
              ShowMessage(E.Message);
            end;
          end;

          //DW  maandag 15/01/2018 15:04:14: DW
          //    kan andere folder zijn als sent mail default niet bestaat
          //    dan mag men dit al niet doen. de code ging ervan uit dat die
          //    altijd bestaan hierboven maar dat is nit het geval
          if bFolderSentMailOk and not VarIsClear(OleFolder) then
          begin
            OleItems := OleFolder.Items;
            TmpItems := nil;
            if Supports(OleItems, _Items, TmpItems) then
              if TmpItems <> nil then
              begin
                iIndex := Length(FItemsArray);
                SetLength(FItemsArray, Length(FItemsArray) + 1);
                FItemsArray[iIndex] := TItems.Create(Self);
                FItemsArray[iIndex].OnItemAdd := ItemsAdd;
                FItemsArray[iIndex].ConnectTo(TmpItems);
              end;
            OleFolder := Unassigned;
          end;
        end;
      end
      else
      begin
        SetLength(FItemsArray, 1);
        FItemsArray[0] := TItems.Create(Self);
        FItemsArray[0].OnItemAdd := ItemsAdd;
        FItemsArray[0].ConnectTo(Self.OutlookApp.GetNamespace('MAPI').GetDefaultFolder(olFolderSentMail).Items);
      end;
    end;
    if DebugTraceMode then DebugLog.Log('End: TAddInModule.SetTrackSentItemsFolder(' + BoolToStr(value, true) + ')');
  except on E: SysUtils.Exception do
    WriteException(E, 'TAddInModule.SetTrackSentItemsFolder');
  end;
end;
Posted 15 Jan, 2018 11:15:15 Top
Tim Smet




Posts: 16
Joined: 2015-10-06
It seems even in vba it tries to create the folders in a pst (or perhaps any store) if they don't exist Is this a bug of some sort ? i can't find any information saying it will try to create these folders if they don't exist


Public Sub test()
Dim aStore As Store
Dim aFolder As Folder

'on error resume next
For Each aStore In Session.Stores
    MsgBox (aStore.DisplayName)
    'this seems to TRY to create the folder if it does not exist in PST's
    Set aFolder = aStore.GetDefaultFolder(olFolderDrafts)
    'these one's usually fail with operation failed message
    Set aFolder = aStore.GetDefaultFolder(olFolderOutbox)
    Set aFolder = aStore.GetDefaultFolder(olFolderSentMail)
    Set aFolder = Nothing
Next
End Sub
Posted 16 Jan, 2018 05:16:26 Top
Andrei Smolin


Add-in Express team


Posts: 14367
Joined: 2006-05-11
Hello Tim,

A while back I noticed a folder named "Edit <0w>" in one of my test PSTs. I was unable to find what created it. Now I run the code that works with that PST; the code calls store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDeletedItems); the weird folder isn't created. I've also run a VBA macro scanning all stores and calling store.GetDefaultfolder(olFolderSentMail) with no effect.

I've googled out a related end-user-level question at https://answers.microsoft.com/en-us/msoffice/forum/msoffice_outlook-mso_other/why-does-a-folder-called-edit-0w-appear-in-my/6532b181-9882-4197-93ae-a7173442bfa2?auth=1. I suppose this was an Outlook issue and Microsoft has fixed it; suggest your customer to update Office.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 16 Jan, 2018 05:23:18 Top
Andrei Smolin


Add-in Express team


Posts: 14367
Joined: 2006-05-11
Another suggestion would be to scan that store for errors using the information at https://support.microsoft.com/en-sg/help/983036/the-scanost-exe-tool-is-not-available-starting-with-outlook-2010.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 16 Jan, 2018 05:27:14 Top
Tim Smet




Posts: 16
Joined: 2015-10-06
Hi Andrei,

The customer is already running latest outlook 2016 not 2010. We will try a scanpst (as it's a pst file not ost).

Also i opened a question on the msdn forums about Store.GetDefaultfolder trying to create the non existing folders first instead of returning null / nothing as is stated in the documentation.

Also i can on my latest version outlook 2016 (insider builds) create the folders on purpose in about 1 in tree times. but on a diffrent way. With client just starting outlook and my addin is enough on my pc i have to use another win32 program to make them appear

Basically you need an addin that loops over the stores and calls the store.getdefaultfolders at startup (like the function in my first post from my addin) and then you just need to use CreateOleObject("outlook.application") from within another application like for example this delphi code:


procedure TOutlookHelper.LookupOutlookversion;
var
  oApp: OleVariant;
  version: Double;
  sVersion: string;
  iPos1, iPos2: Integer;
begin
  FOutlookVersion := ovUnknown;
  FOutlookFullVersionStr := '';
  try
    oApp := CreateOleObject('Outlook.Application');
    try
      FOutlookFullVersionStr := oApp.Version;
      sVersion := FOutlookFullVersionStr;
      if sVersion <> '' then
      begin
        iPos1 := Posstr('.', sVersion);
        iPos2 := PosStr('.', sVersion, iPos1 +1);

        //DW  Max 1 "."
        if iPos2 > 0 then
          sVersion := StrLeft(sVersion, iPos2-1);

        sVersion := StrTran(sVersion, '.', DecimalSeparator);

        Version := StrToFloat(sVersion);
        if version < 8.5 then
          FOutlookVersion := ovOutlook97
        else if version < 9 then
          FOutlookVersion := ovOutlook98
        else if version < 10 then
          FOutlookVersion := ovOutlook2000
        else if version < 11 then
          FOutlookVersion := ovOutlook2002
        else if version < 12 then
          FOutlookVersion := ovOutlook2003
        else if version < 14 then
          FOutlookVersion := ovOutlook2007
        else if version < 15 then
          FOutlookVersion := ovOutlook2010
        else if version < 16 then
          FOutlookVersion := ovOutlook2013
        else
          FOutlookVersion := ovUnknown;
      end;
    finally
      oApp := Unassigned;
    end;
  except
  end;
end;


if you run above code when outlook 2016 is not running it will start outlook process and show an informational icon in the system tray stating another application is using outlook.

If i do this code above in combination with an addin calling the function stated in my 1st post at startup it will create those weird edit folders in like one out of 3 times with me
Posted 16 Jan, 2018 05:58:25 Top
Andrei Smolin


Add-in Express team


Posts: 14367
Joined: 2006-05-11
Hello Tim,

I've found your question at https://social.msdn.microsoft.com/Forums/en-US/81f29259-4010-453b-8cd7-0ec336764ae1/storegetdefaultfolder-is-trying-to-create-folders-in-a-pst-if-they-dont-exist-instead-of?forum=outlookdev and responded to it.

I can't reproduce the issue using an add-in that calls Store.GetDefaultFolder(olFolderDeletedItems) and starting Outlook using CreateObject("Outlook.Application") from VBA.

Please confirm all other add-ins are turned off.

If your PST has some files/folders in Deleted Items, try right-clicking that folder and choosing Empty folder on the context menu.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 17 Jan, 2018 08:29:10 Top
Tim Smet




Posts: 16
Joined: 2015-10-06
Hi andrei,

here is a youtube video showing the problem by creating a vsto plugin in visual studio it exhibits the same behaviour as what i see with add in express:

here's a video showing the problem i also posted it on the msdn forums

the only addins loaded are the vsto plugin i mentioned on the msdn forums and outlook vba addin nothing else in the video and i created a new pst file during the video. so the problem is not the pst either. I really think outlook is trying to create folders when calling store.gedefaultfolder and sometimes fails creating those folder ending up with these weird named ones.

Or when using our complete addin using addin express only that addin + delphi program that does createoleobject('outlook.application');

my outlook is being used in dutch language though but i doubt this could have an effect. and my outlook 2016 version is 1712 build 8827.2148
Posted 17 Jan, 2018 09:32:51 Top
Andrei Smolin


Add-in Express team


Posts: 14367
Joined: 2006-05-11
Hello Tim,

I was able to reproduce the "Cannot create ActiveX component" exception that your video shows. I put it here for reference.

System.Exception: Cannot create ActiveX component.
at Microsoft.VisualBasic.Interaction.CreateObject(String ProgId, String ServerName)
at WindowsApplication2.Form1.Button1_Click(Object sender, EventArgs e) in D:\_Projects\_tests\_Andrei Smolin\WindowsApplication2\WindowsApplication2\Form1.vb:line 6
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.8825 (WinRelRS3.050727-8800)
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
----------------------------------------
WindowsApplication2
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///D:/_Projects/_tests/_Andrei%20Smolin/WindowsApplication2/WindowsApplication2/bin/Debug/WindowsApplication2.exe
----------------------------------------
Microsoft.VisualBasic
Assembly Version: 8.0.0.0
Win32 Version: 8.0.50727.8825 (WinRelRS3.050727-8800)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.VisualBasic/8.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
System
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.8825 (WinRelRS3.050727-8800)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Windows.Forms
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.8825 (WinRelRS3.050727-8800)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.8825 (WinRelRS3.050727-8800)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.8825 (WinRelRS3.050727-8800)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.8827 (WinRelRS3.050727-8800)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Runtime.Remoting
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.8825 (WinRelRS3.050727-8800)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Runtime.Remoting/2.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
Microsoft.Office.Interop.Outlook
Assembly Version: 15.0.0.0
Win32 Version: 15.0.4569.1507
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Microsoft.Office.Interop.Outlook/15.0.0.0__71e9bce111e9429c/Microsoft.Office.Interop.Outlook.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.


Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 18 Jan, 2018 01:52:35 Top