2

I have a module that will automate Outlook but it should be skipped if Outlook isn't available.

Simply checking whether Outlook is installed is not sufficient because if there is a fresh Office install, launching Outlook will simply launch the configuration wizard. From my POV, Outlook is not available for automation so the module shouldn't be used even though it might be installed.

From my tests and the suggestions in this question, I can successfully trap for whether Outlook isn't configured yet but there is an edge case where this fails. This is when there is a dialog that asks to select a profile. In this situation, the check returns true but Outlook is actually not usable for the purposes of automation due to still needing additional configuration (e.g. selecting a profile). Is it possible to also trap this edge case?

To reproduce the "Select Profile" issue, go to Control Panel -> Mail. On the dialog, there is a option to "When starting Microsoft Outlook, use this profile" - select "Prompt for a profile used". When you then launch Outlook, you are asked to choose a profile. That is the case when the code below will fail.

This is my almost-working code so far...

Public Function DetectOutlookProfile() As Boolean
    Dim objOutlook As Object
    Dim objReg As Object
    Dim varSplit As Variant
    Dim lngMajor As Long
    Dim strPath As String
    Dim varSubKeys As Variant
    Dim varSubKey As Variant

    Const HKEY_CURRENT_USER As Long = &H80000001

On Error GoTo ErrHandler

    Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

    'Get an instance of Outlook so that we can determine the version
    'being currently used by the current user. 
    Set objOutlook = CreateObject("Outlook.Application")
    varSplit = Split(objOutlook.Version, ".")
    lngMajor = varSplit(0)
    If lngMajor <= 14 Then
        'Outlook profile isn't version specific for Outlook 97-2010
        strPath = "Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles"
    Else
        'Outlook profile is version specific for Outlook 2013+
        strPath = "Software\Microsoft\Office\" & lngMajor & ".0\Outlook\Profiles"
    End If

    objReg.EnumKey HKEY_CURRENT_USER, strPath, varSubKeys
    For Each varSubKey In varSubKeys
        DetectOutlookProfile = True
        Exit For
    Next

ExitProc:
    On Error Resume Next
    Exit Function
ErrHandler:
    'Silently fail and return false
    Select Case Err.Number
        Case Else
            DetectOutlookProfile = False
            Debug.Print Err.Number & " (" & Err.Description & ")"
    End Select
    Resume ExitProc
    Resume
End Function
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
this
  • 1,406
  • 11
  • 23
  • Is [this](http://www.access-programmers.co.uk/forums/showthread.php?t=225555) or [this](https://msdn.microsoft.com/en-us/library/office/ff861594.aspx) helpful at all? – David Zemens Oct 12 '15 at 15:21
  • I doubt it - I'm not interested in logging into any particular profile. This is something that should only run when there is a profile selected and Outlook is fully configured. I have no intention of automatically configuring the Outlook. If it's not there, then the module just shouldn't be executed. So, `LogOn` method doesn't really help me here. – this Oct 12 '15 at 15:25
  • OK, so you **don't** want to execute the module using the Outlook default profile? – David Zemens Oct 12 '15 at 15:27
  • Hm, actually, I do. I actually don't care _which_ profile it is, as long it's already selected by Outlook. I just am not going to do any configuration of Outlook. But when there's a Select Profile dialog, IMPOV, user hasn't completed the configuration and therefore the module shouldn't be used until they finish configuring Outlook and they must do it themselves, not by my code. – this Oct 12 '15 at 15:29
  • *user hasn't completed the configuration* -- OR, they've deliberately configured Outlook to *prompt* them for which profile to use, each session. :) – David Zemens Oct 12 '15 at 15:31
  • The MSDN article suggests: *If Outlook is not running and you only want to start Outlook with the default profile, do not use the Logon method.* and then using the `InitializeMAPI` function. I haven't tested this for your case, but it looks like it *might* do it. – David Zemens Oct 12 '15 at 15:33
  • Fair point, David. However, from my POV, I can't use the Outlook for automation unless I actually do a `Login`. I guess I'm still stuck needing to know whether they have configured Outlook this way so that even if that is a problem, I would need to get user's profile selection somehow to be passed into the sample code or if I'm not given an user's profile, to not proceed any further with the automation. I'll check the `InitializeMAPI` out. Thanks. – this Oct 12 '15 at 15:34
  • *first, instantiate the Outlook Application object, then reference a default folder such as the Inbox. This has the side effect of initializing MAPI to use the default profile and to make the object model fully functional.* -- is this not what you want? Or, does the functional code in your procedures require the user to be logged on to a specific profile? – David Zemens Oct 12 '15 at 15:36

1 Answers1

0

Thanks to @David Zemens' suggestions, I found a solution that seems to work.

It seems that I don't even need to bother with registry checks. I can simply do this instead:

Set objOutlook = CreateObject("Outlook.Application") 
DetectOutlookProfile = Len(objOutlook.GetNamespace("MAPI").CurrentProfileName)

Which will return 0 whether the Outlook has no profiles or is requiring a manual profile selection.

I suppose the registry check is needed to determine whether the Outlook has any profiles configured so that one's code could be then written to manually prompt the user for profile to be passed into Login method. For my case, I just don't want to run the module in either case, so the checking Len() of the current profile name suffices.

this
  • 1,406
  • 11
  • 23