Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to *Really* .Quit Outlook Application Object?

Status
Not open for further replies.

jsteph

Technical User
Oct 24, 2002
2,562
US
Hi all,
I'm sending some emails from Access via Outlook. In general, the pseudocode is below:
Code:
Set olNS = olApp.GetNamespace("MAPI")
Set olFolder = olNS.GetDefaultFolder(olFolderOutbox)
'Prepare message, send mail
'...blah, blah...
Set olExpl = olApp.Explorers.Add(olNS.GetDefaultFolder(olFolderOutbox), olFolderDisplayNormal)
olExpl.CommandBars("Tools").Controls("Send/Receive").Controls(1).Execute
olExpl.Close
Set olExpl = Nothing
olApp.Quit
set olApp = Nothing
BTW, I've tried this using early and late binding.

But either way, when I get to the olApp.Quit line, it has no error and steps through it normally, but in the Task Manager I still see Outlook.exe sitting there. And when the next email is sent (this is on a timer) yet another Outlook.exe appears in the task manager...and another and another. And they each take up 40-50-meg.

I've tried using GetObject() thinking it would get the instance that's out there, but no, it creaets a new one.

So bottom line--how do I 'really, really, for sure' Quit the outlook app?
Thanks,
--Jim
 
>the pseudocode is below

The problem is probably due to an unqualified reference to an Outlook object in your code (given a ref into an Outlook library for the Constants). I cannot see an unqualified ref in your excerpt, but I am no Outlook VBA expert. Maybe the full code would reveal something.
 
No...that was my mistake in pasting, all references are fine.

I think it might be that I'm opening the Outlook VBA editor from within Access, and there is no .Close method (that I know of) for that.

I'll gather more code to paste, I was just trying to keep clutter down and that's why I'd removed chunks, including the olApp and other assignments.
--Jim
 
I think it might be that I'm opening the Outlook VBA editor from within Access"

You are opening the Outlook VBA editor???????

faq219-2884

Gerry
My paintings and sculpture
 
Fumei,
Yes, apparently Microsoft's botched implementation of Outlook OLE will not allow an exposed outlook *user* function to fire from Access (or I'd assume Excel or other ole client) unless the outlook vba enviroment is opened.

Yes I know, it sounds crazy. I've tried it withoug opening the editor and the function won't fire. Opening the vba environment (via a convoluted method of finding a menu-item and .executing it) allows the outlook (user) function to fire from Access.

And this all works--I send the mail automatically without the security prompt. But the .Quit method of the Outlook.Application object fails, and by trial and error I found that it's due to the vba editor remaining open. I know of no way to close it gracefully, I've been getting by using the TerminateProcess api after using FindWindow to get the vba window handle, and then the process id.

It shouldn't be this difficult.
Thanks for any help...
--Jim
 
Wow. I guess Access is different. You can use an instance of Outlook, and execute code in it, from Word, or Excel, without opening the Outlook VBE.

How, exactly, are you opening the Outlook VBE?

faq219-2884

Gerry
My paintings and sculpture
 
Fumei,
fumei said:
You can use an instance of Outlook, and execute code in it, from Word, or Excel, without opening the Outlook VBE.
Yes I know, and you can do that with Access as well--I have several Access and Excel apps that control Outlook with no problem.

Buy my situation is to solve a speciific bug introduced in a service pack. The background is this: After a certan service pack (and I'm not even sure if it's an Access, Outlook, or Windows SP) what happens is that when you call the Outlook .Send method of and Email Object, a security warning pops up and says "A program is sending mail on your behalf--this might be a virus...Click Yes to allow"

This might seem like a minor annoyance but remember this is "automation". I'm not at the computer. It's a scheduled task that runs at 3 AM and nobody's there to "Click Yes". To combat this there are entire cottage industries selling "Click Yes" programs that will mimick a mouseclick automatically when that dialog pops up (Google Click Yes and you'll see). Obviously, I don't want robots blindly clicking a Yes button on a server with dozens of apps running.

So the solution is to call the .Send from a "Trusted" program, which in Microsoft's world can only be Outlook itself. So I found code at EverythingAccess.com, in the below link:
[link
]EverythingAccess Outlook Fix[/url]

So I've only slightly modified the code in the above link, changing numeric constants for the enumerated constants so the code is more readable, but the lines below:
Code:
Set objExplorer = objOutlook.Explorers.Add(objNameSpace.Folders(1), 0)
objExplorer.CommandBars.FindControl(, 1695).Execute
...opens an Outlook Explorer instance and the 1695 is the menu item "Open Visual Basic Editor" in outlook.

That code is executed from Access, the first function is executed from Outlook. One thing I changed is the naming, it's very confusing: the function FnSendMailSafe is the fcn. that resides in Outlook, and the function FnSafSendEmail is the one that *calls* FnSendMailSafe. But that's beside the point--the point is that this all works as far as no popup happening, but I have tried to enumerate the controls to find the "Close Editor" menu item in the vba window and havn't found it.

My program is actually working fine, but I just don't like killing an outlook window via the api, I'd rather do it gracefully from the Ojbect model.
--Jim
 
Why bother with MACRO like steps.

This requires no security interaction, at least it does in 2003.
Code:
Sub dx()
    Dim msg_txt As String, msg_sub As String, msg_to As String
    
    msg_txt = "message text "
    
    msg_sub = "message subject"
    msg_to = "someid@someserver.com"
    
    
    CdoSend msg_to, "msg_to, msg_sub, msg_txt"


End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Public Function CdoSend(MailTo As String, MailFrom As String, Subject As String, MessageText As String, Optional CC As String, Optional BCC As String, Optional FileAttachment As String) As Boolean
On Error GoTo CdoSend_Err

' This example use late binding, you don't have to set a reference
' You must be online when you run the sub
    Dim oMsg As Object
    Dim oConf As Object
    Dim Flds As Variant
 
    Set oMsg = CreateObject("CDO.Message")
    Set oConf = CreateObject("CDO.Configuration")
 
        oConf.Load -1    ' CDO Source Defaults
        Set Flds = oConf.Fields
        With Flds
            .Item("[URL unfurl="true"]http://schemas.microsoft.com/cdo/configuration/sendusing")[/URL] = 2
            .Item("[URL unfurl="true"]http://schemas.microsoft.com/cdo/configuration/smtpserver")[/URL] = "somemailserver.com"
            .Item("[URL unfurl="true"]http://schemas.microsoft.com/cdo/configuration/smtpserverport")[/URL] = 25
            .Update
        End With
 
    With oMsg
        Set .Configuration = oConf
        
        .To = MailTo
        .CC = CC
        .BCC = BCC
        .FROM = MailFrom
        
        .Subject = Subject
        .TextBody = MessageText

        
        If Len(FileAttachment & "") > 0 Then
            
            '## Last make sure the file actually exists and send it!:
            Dim fso
            Set fso = CreateObject("Scripting.FileSystemObject")
            If fso.FileExists(FileAttachment) Then
                .AddAttachment FileAttachment
            Else
                'otherwise return that the send failed and exit function:
                Debug.Print "[CdoSend.Error]=> File attachment path does not exist, quitting..."
                CdoSend = False
                Exit Function
            End If
        
        End If
    
        '## Send zee message! ##
        .sEnd
    
    End With

    Set fso = Nothing
    Set oMsg = Nothing
    Set oConf = Nothing
    
    CdoSend = True

CdoSend_Exit:
    Exit Function
    
CdoSend_Err:
    Debug.Print "[CdoSend.Error(" & Err.Number & ")]=> " & Err.Description
    CdoSend = False
    Resume CdoSend_Exit
End Function

Skip,

[glasses]Just traded in my old subtlety...
for a NUANCE![tongue]
 
Hi:

What Skip is giving you is a tried and true method of sending without involving Outlook. If you are using Outlook 2003 and above, there is no way of keeping this warning from happening.

However, in OL 2007, there is a setting in Options.

You can, however, start your macros in Outlook, using the Outlook application, to keep this from happening.

I hope this helps.

Ron Repp

If gray hair is a sign of wisdom, then I'm a genius.

My newest novel: Wooden Warriors
 
Yes, I'm aware of other methods, I had a third-party emailer called Chilkat that I used for a while. It too worked well without the security warning.

However I need the Sent folder for verification. I need to have a user friendly verification/resending ability and it has to fit within our corporate email system--which is Exchange, so Outlook is the only realistic choice.

Again, the method I found on that site does indeed work and avoids the Security prompt, it just boils down to the .Quit method which that fix torpedoed. So what I'll likely do is stick with the FindWindow/Terminate Process method of .Quitting, until we get Office 2007.
--Jim
 
I use "Advanced Security for Outlook: from
with my vfp automation of outlook. It has to be installed and run once on each workstation but it solves the problem with ol2003
wjwjr

This old world keeps spinning round - It's a wonder tall trees ain't layin' down
 
FWIW,

I've run in to the exact same problem, trying to automate sending email using Outlook 2003 from Excel VBA. Everything works fine, except the .Quit method doesn't actually quit the process.

It works fine if it can grab a running process, but if we have to start an instance of Outlook.Application from code, I can't quit that instance from code. I was thinking along the same lines: I'll have to find the windows and terminate the process...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top