Handling application.quit event

Status
Not open for further replies.
K

kostas

Hello, i am developing an exe application and i use global object to declare

outlook application withevents. I use outlook 2007 sp2 and i am having

trouble releasing my variable references or reusing then. I use this code :

Public Class StartOE

Private WithEvents o As Outlook.Application = Nothing

Private ns As Outlook.NameSpace = Nothing

Private omFolder As Outlook.MAPIFolder = Nothing

Public Sub New()

If detectOutlook() Then

o = GetObject(, "Outlook.Application")

Else

o = New Outlook.Application

End If

Try

ns = o.GetNamespace("MAPI") ' get namespace

ns.Logon("", "", True, True) 'log into new Outlook session

omFolder =

ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder

If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show

explorer

Catch ex As Exception

Err.Clear()

End Try

End Sub

Private Sub o_Quit() Handles o.Quit

' MsgBox("quit")

If Not omFolder Is Nothing Then Marshal.ReleaseComObject(omFolder)

If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)

If Not o Is Nothing Then Marshal.ReleaseComObject(o)

omFolder = Nothing

ns = Nothing

o = Nothing 'Causes RPC exception

GC.Collect()

GC.WaitForPendingFinalizers()

GC.Collect()

GC.WaitForPendingFinalizers()

End Sub

End Class

The problem starts when the user closes outlook and the event triggers .

I know that when quit event is executed, outlook releases all its references

to external objects, so i am getting RPC exception setting object o to

nothing (see my code). I do not want to prevent users from closing outlook, i

just want to be able to launch outlook again using the same declared objects.

I get this error even if, after the execution of quit event, i try to set "

o = New Outlook.Application" . Can anyone point me to a workaround? I want to

be able to reuse 'o' object using 'new' or getobject.

Thank you in advance
 
K

Ken Slovak - [MVP - Outlook]

I'm not sure why you're using a logon calling for a new session and a logon

dialog. If Outlook is already running you usually use a logon of Logon("",

"", False, False).

To get an event for when Outlook is closing before Quit() fires and Outlook

objects are out of scope you can trap the Explorer.Close() event. If there

are no other Explorers and no Inspectors are open then Outlook is closing

and you can release your objects then.

"kostas" <kostas> wrote in message

news:0912C588-26D1-4935-9178-888AF5827738@microsoft.com...
> Hello, i am developing an exe application and i use global object to
> declare
> outlook application withevents. I use outlook 2007 sp2 and i am having
> trouble releasing my variable references or reusing then. I use this code
> :

> Public Class StartOE
> Private WithEvents o As Outlook.Application = Nothing
> Private ns As Outlook.NameSpace = Nothing
> Private omFolder As Outlook.MAPIFolder = Nothing

> Public Sub New()
> If detectOutlook() Then
> o = GetObject(, "Outlook.Application")
> Else
> o = New Outlook.Application
> End If

> Try
> ns = o.GetNamespace("MAPI") ' get namespace
> ns.Logon("", "", True, True) 'log into new Outlook session
> omFolder =
> ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> explorer
> Catch ex As Exception
> Err.Clear()
> End Try
> End Sub

> Private Sub o_Quit() Handles o.Quit
> ' MsgBox("quit")
> If Not omFolder Is Nothing Then Marshal.ReleaseComObject(omFolder)
> If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)
> If Not o Is Nothing Then Marshal.ReleaseComObject(o)
> omFolder = Nothing
> ns = Nothing
> o = Nothing 'Causes RPC exception
> GC.Collect()
> GC.WaitForPendingFinalizers()
> GC.Collect()
> GC.WaitForPendingFinalizers()
> End Sub
> End Class

> The problem starts when the user closes outlook and the event triggers .
> I know that when quit event is executed, outlook releases all its
> references
> to external objects, so i am getting RPC exception setting object o to
> nothing (see my code). I do not want to prevent users from closing
> outlook, i
> just want to be able to launch outlook again using the same declared
> objects.
> I get this error even if, after the execution of quit event, i try to set
> "
> o = New Outlook.Application" . Can anyone point me to a workaround? I want
> to
> be able to reuse 'o' object using 'new' or getobject.
> Thank you in advance
 
K

kostas

Thank you for your answer. I will try the workaround you mentioned and post

the code here tomorrow.
wrote:


> I'm not sure why you're using a logon calling for a new session and a logon
> dialog. If Outlook is already running you usually use a logon of Logon("",
> "", False, False).

> To get an event for when Outlook is closing before Quit() fires and Outlook
> objects are out of scope you can trap the Explorer.Close() event. If there
> are no other Explorers and no Inspectors are open then Outlook is closing
> and you can release your objects then.

> >

>

> "kostas" <kostas> wrote in message
> news:0912C588-26D1-4935-9178-888AF5827738@microsoft.com...
> > Hello, i am developing an exe application and i use global object to
> > declare
> > outlook application withevents. I use outlook 2007 sp2 and i am having
> > trouble releasing my variable references or reusing then. I use this code
> > :
> > Public Class StartOE
> > Private WithEvents o As Outlook.Application = Nothing
> > Private ns As Outlook.NameSpace = Nothing
> > Private omFolder As Outlook.MAPIFolder = Nothing
> > Public Sub New()
> > If detectOutlook() Then
> > o = GetObject(, "Outlook.Application")
> > Else
> > o = New Outlook.Application
> > End If
> > Try
> > ns = o.GetNamespace("MAPI") ' get namespace
> > ns.Logon("", "", True, True) 'log into new Outlook session
> > omFolder =
> > ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> > If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> > explorer
> > Catch ex As Exception
> > Err.Clear()
> > End Try
> > End Sub
> > Private Sub o_Quit() Handles o.Quit
> > ' MsgBox("quit")
> > If Not omFolder Is Nothing Then Marshal.ReleaseComObject(omFolder)
> > If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)
> > If Not o Is Nothing Then Marshal.ReleaseComObject(o)
> > omFolder = Nothing
> > ns = Nothing
> > o = Nothing 'Causes RPC exception
> > GC.Collect()
> > GC.WaitForPendingFinalizers()
> > GC.Collect()
> > GC.WaitForPendingFinalizers()
> > End Sub
> > End Class
> > The problem starts when the user closes outlook and the event triggers .
> > I know that when quit event is executed, outlook releases all its
> > references
> > to external objects, so i am getting RPC exception setting object o to
> > nothing (see my code). I do not want to prevent users from closing
> > outlook, i
> > just want to be able to launch outlook again using the same declared
> > objects.
> > I get this error even if, after the execution of quit event, i try to set
> > "
> > o = New Outlook.Application" . Can anyone point me to a workaround? I want
> > to
> > be able to reuse 'o' object using 'new' or getobject.
> > Thank you in advance


> .
>
 
K

kostas

Hello again, it seems that even if i trap explorer.close event, all objects

are automatically released. I now get error "COM object that has been

separated from its underlying RCW can not be used". Can anyone please point

me to what am i doing wrong?

Here is my code:

Public Class StartO

Private WithEvents o As Outlook.Application = Nothing

Private ns As Outlook.NameSpace = Nothing

Private WithEvents ex As Outlook.Explorer

Private omFolder As Outlook.MAPIFolder = Nothing

Public Sub New()

If detectOutlook() Then

o = GetObject(, "Outlook.Application")

ns = o.GetNamespace("MAPI") ' get namespace

ns.Logon("", "", False, False) 'log into new Outlook session

Else

o = New Outlook.Application

ns = o.GetNamespace("MAPI") ' get namespace

ns.Logon("", "", False, True) 'log into new Outlook session

End If

Try

omFolder =

ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder

If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show

explorer

ex = o.ActiveExplorer

Catch ex As Exception

Err.Clear()

End Try

End Sub

Private Sub ex_Close() Handles ex.Close

Try

If o.Inspectors.Count = 0 Then 'here i get the error

If o.Explorers.Count = 0 Then 'or sometimes here

If Not omFolder Is Nothing Then

Marshal.ReleaseComObject(omFolder)

If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)

If Not o Is Nothing Then Marshal.ReleaseComObject(o)

omFolder = Nothing

ns = Nothing

o = Nothing

GC.Collect()

GC.WaitForPendingFinalizers()

GC.Collect()

GC.WaitForPendingFinalizers()

End If

End If

Catch ex As Exception

Err.Clear()

End Try

End Sub

End Class

"kostas" wrote:


> Thank you for your answer. I will try the workaround you mentioned and post
> the code here tomorrow.

> " - " wrote:
>
> > I'm not sure why you're using a logon calling for a new session and a logon
> > dialog. If Outlook is already running you usually use a logon of Logon("",
> > "", False, False).
> > To get an event for when Outlook is closing before Quit() fires and Outlook
> > objects are out of scope you can trap the Explorer.Close() event. If there
> > are no other Explorers and no Inspectors are open then Outlook is closing
> > and you can release your objects then.
> > > >

> >

> > "kostas" <kostas> wrote in message
> > news:0912C588-26D1-4935-9178-888AF5827738@microsoft.com...
> > > Hello, i am developing an exe application and i use global object to
> > > declare
> > > outlook application withevents. I use outlook 2007 sp2 and i am having
> > > trouble releasing my variable references or reusing then. I use this code
> > > :
> > > > Public Class StartOE
> > > Private WithEvents o As Outlook.Application = Nothing
> > > Private ns As Outlook.NameSpace = Nothing
> > > Private omFolder As Outlook.MAPIFolder = Nothing
> > > > Public Sub New()
> > > If detectOutlook() Then
> > > o = GetObject(, "Outlook.Application")
> > > Else
> > > o = New Outlook.Application
> > > End If
> > > > Try
> > > ns = o.GetNamespace("MAPI") ' get namespace
> > > ns.Logon("", "", True, True) 'log into new Outlook session
> > > omFolder =
> > > ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> > > If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> > > explorer
> > > Catch ex As Exception
> > > Err.Clear()
> > > End Try
> > > End Sub
> > > > Private Sub o_Quit() Handles o.Quit
> > > ' MsgBox("quit")
> > > If Not omFolder Is Nothing Then Marshal.ReleaseComObject(omFolder)
> > > If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)
> > > If Not o Is Nothing Then Marshal.ReleaseComObject(o)
> > > omFolder = Nothing
> > > ns = Nothing
> > > o = Nothing 'Causes RPC exception
> > > GC.Collect()
> > > GC.WaitForPendingFinalizers()
> > > GC.Collect()
> > > GC.WaitForPendingFinalizers()
> > > End Sub
> > > End Class
> > > > The problem starts when the user closes outlook and the event triggers .
> > > I know that when quit event is executed, outlook releases all its
> > > references
> > > to external objects, so i am getting RPC exception setting object o to
> > > nothing (see my code). I do not want to prevent users from closing
> > > outlook, i
> > > just want to be able to launch outlook again using the same declared
> > > objects.
> > > I get this error even if, after the execution of quit event, i try to set
> > > "
> > > o = New Outlook.Application" . Can anyone point me to a workaround? I want
> > > to
> > > be able to reuse 'o' object using 'new' or getobject.
> > > Thank you in advance

> > .
> >
 
K

Ken Slovak - [MVP - Outlook]

The RCW error is when you access a COM component where the wrapper for the

CLR on that COM object has already been released.

Explorer.Close() should fire long enough before any Quit() events so that

your Outlook objects should still be in scope and not released yet. You can

and should first test for (Outlook.Explorers != null), however in the

Explorer.Close() event that collection should never be null unless you are

releasing your Explorers collection object prior to that event.

"kostas" <kostas> wrote in message

news:53D092FB-0466-46DD-A7E5-D6FCF715EE02@microsoft.com...
> Hello again, it seems that even if i trap explorer.close event, all
> objects
> are automatically released. I now get error "COM object that has been
> separated from its underlying RCW can not be used". Can anyone please
> point
> me to what am i doing wrong?
> Here is my code:

> Public Class StartO
> Private WithEvents o As Outlook.Application = Nothing

> Private ns As Outlook.NameSpace = Nothing

> Private WithEvents ex As Outlook.Explorer

> Private omFolder As Outlook.MAPIFolder = Nothing

> Public Sub New()
> If detectOutlook() Then
> o = GetObject(, "Outlook.Application")
> ns = o.GetNamespace("MAPI") ' get namespace
> ns.Logon("", "", False, False) 'log into new Outlook session
> Else
> o = New Outlook.Application
> ns = o.GetNamespace("MAPI") ' get namespace
> ns.Logon("", "", False, True) 'log into new Outlook session
> End If

> Try
> omFolder =
> ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> explorer
> ex = o.ActiveExplorer
> Catch ex As Exception
> Err.Clear()
> End Try

> End Sub

> Private Sub ex_Close() Handles ex.Close
> Try
> If o.Inspectors.Count = 0 Then 'here i get the error
> If o.Explorers.Count = 0 Then 'or sometimes here
> If Not omFolder Is Nothing Then
> Marshal.ReleaseComObject(omFolder)
> If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)
> If Not o Is Nothing Then Marshal.ReleaseComObject(o)
> omFolder = Nothing
> ns = Nothing
> o = Nothing
> GC.Collect()
> GC.WaitForPendingFinalizers()
> GC.Collect()
> GC.WaitForPendingFinalizers()
> End If
> End If
> Catch ex As Exception
> Err.Clear()
> End Try

> End Sub
> End Class
 
K

kostas

Hello again ken and thank you for your precious help. I have created a new

project in vs2008 just to make sure that i do not release any objects by

mistake. This code runs really well as long as there is no outlook running.

the close event fires and i can release all objects. The problem is that if

outlook is running i am getting the same RCW error for object "explorer" as

long as the close event fires. In this case senario :

1. outlook 2007 is running

2. my program runs and gets a reference to running outlook using getobject.

3. user closes outlook

4. close event fires,

5. vs2008 seems to be busy for a few seconds

6. A small blue dot appears at breakpoint "the process or thread has

changed since last step"

7. i catch RCW error

This is all the code i use:

Imports Microsoft.Office.Interop

Imports System

Imports System.IO

Public Class Form1

Private WithEvents o As Outlook.Application = Nothing

Private ns As Outlook.NameSpace = Nothing

Private WithEvents explorer As Outlook.Explorer

Private omFolder As Outlook.MAPIFolder = Nothing

Private Declare Function FindWindow Lib "user32" Alias _

"FindWindowA" (ByVal lpClassName As String, _

ByVal lpWindowName As IntPtr) As IntPtr

Public Sub New1()

If detectOutlook() Then

o = GetObject(, "Outlook.Application")

ns = o.GetNamespace("MAPI") ' get namespace

ns.Logon("", "", False, False) 'log into Outlook session

Else

o = New Outlook.Application

ns = o.GetNamespace("MAPI") ' get namespace

ns.Logon("", "", False, True) 'log into new Outlook session

End If

Try

omFolder =

ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder

If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show

explorer()

explorer = o.ActiveExplorer

Catch ex1 As Exception

Err.Clear()

End Try

End Sub

Private Function detectOutlook() As Boolean

detectOutlook = False

Dim hwnd As IntPtr

hwnd = FindWindow("rctrl_renwnd32", IntPtr.Zero)

If hwnd <> IntPtr.Zero Then Return True

End Function

Private Sub ex_Close() Handles explorer.Close

'this works fine if i create outlook application using o = New

Outlook.Application

Try

If Not o.Explorers Is Nothing Then

If o.Explorers.Count = 0 Then

If Not omFolder Is Nothing Then

Marshal.ReleaseComObject(omFolder)

If Not explorer Is Nothing Then

Marshal.ReleaseComObject(explorer)

explorer = Nothing

If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)

If Not o Is Nothing Then Marshal.ReleaseComObject(o)

omFolder = Nothing

ns = Nothing

o = Nothing

GC.Collect()

GC.WaitForPendingFinalizers()

GC.Collect()

GC.WaitForPendingFinalizers()

End If

End If

End If

Catch ex1 As Exception

Err.Clear() 'Here i catch RCW error

End Try

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles Button1.Click

New1()

End Sub

End Class
wrote:


> The RCW error is when you access a COM component where the wrapper for the
> CLR on that COM object has already been released.

> Explorer.Close() should fire long enough before any Quit() events so that
> your Outlook objects should still be in scope and not released yet. You can
> and should first test for (Outlook.Explorers != null), however in the
> Explorer.Close() event that collection should never be null unless you are
> releasing your Explorers collection object prior to that event.

> >

>

> "kostas" <kostas> wrote in message
> news:53D092FB-0466-46DD-A7E5-D6FCF715EE02@microsoft.com...
> > Hello again, it seems that even if i trap explorer.close event, all
> > objects
> > are automatically released. I now get error "COM object that has been
> > separated from its underlying RCW can not be used". Can anyone please
> > point
> > me to what am i doing wrong?
> > Here is my code:
> > Public Class StartO
> > Private WithEvents o As Outlook.Application = Nothing
> > Private ns As Outlook.NameSpace = Nothing
> > Private WithEvents ex As Outlook.Explorer
> > Private omFolder As Outlook.MAPIFolder = Nothing
> > Public Sub New()
> > If detectOutlook() Then
> > o = GetObject(, "Outlook.Application")
> > ns = o.GetNamespace("MAPI") ' get namespace
> > ns.Logon("", "", False, False) 'log into new Outlook session
> > Else
> > o = New Outlook.Application
> > ns = o.GetNamespace("MAPI") ' get namespace
> > ns.Logon("", "", False, True) 'log into new Outlook session
> > End If
> > Try
> > omFolder =
> > ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> > If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> > explorer
> > ex = o.ActiveExplorer
> > Catch ex As Exception
> > Err.Clear()
> > End Try
> > End Sub
> > Private Sub ex_Close() Handles ex.Close
> > Try
> > If o.Inspectors.Count = 0 Then 'here i get the error
> > If o.Explorers.Count = 0 Then 'or sometimes here
> > If Not omFolder Is Nothing Then
> > Marshal.ReleaseComObject(omFolder)
> > If Not ns Is Nothing Then Marshal.ReleaseComObject(ns)
> > If Not o Is Nothing Then Marshal.ReleaseComObject(o)
> > omFolder = Nothing
> > ns = Nothing
> > o = Nothing
> > GC.Collect()
> > GC.WaitForPendingFinalizers()
> > GC.Collect()
> > GC.WaitForPendingFinalizers()
> > End If
> > End If
> > Catch ex As Exception
> > Err.Clear()
> > End Try
> > End Sub
> > End Class


> .
>
 
K

Ken Slovak - [MVP - Outlook]

I don't use VB.NET very often, but I don't really use GetObject() at all in

managed code. I'm not saying it doesn't work or has bad effects, I just

don't use it. What I do use when I want to get an Outlook instance in a

standalone program is something like this, which is a C# procedure. It

shouldn't be hard to translate to VB.NET though:

private void InstantiateOutlook()

{

try

{

System.Diagnostics.Process[] processes =

System.Diagnostics.Process.GetProcessesByName("OUTLOOK");

int collCount = processes.Length;

if (collCount != 0)

{

// Outlook already running, hook into the Outlook instance

outlookApp = Marshal.GetActiveObject("Outlook.Application") as

Outlook.Application;

}

if (outlookApp != null)

{

canQuit = false;

}

else

{

// Outlook not already running, start it

outlookApp = new Outlook.Application();

canQuit = true;

}

if (outlookApp != null)

{

if (canQuit)

{

ns = outlookApp.GetNamespace("MAPI");

ns.Logon(System.Reflection.Missing.Value,

System.Reflection.Missing.Value, System.Reflection.Missing.Value,

System.Reflection.Missing.Value);

}

else

{

// Outlook was running, just hook into existing Session

ns = outlookApp.Session;

}

}

}

catch (System.Exception ex)

{

MessageBox.Show(ex.Message);

}

}

And I handle Explorer.Close() as well as Application.Quit() to do my

shutdowns.

"kostas" <kostas> wrote in message

news:7203E1F0-26A1-4E15-922C-6C9E1F7BCE41@microsoft.com...
> Hello again ken and thank you for your precious help. I have created a new
> project in vs2008 just to make sure that i do not release any objects by
> mistake. This code runs really well as long as there is no outlook
> running.
> the close event fires and i can release all objects. The problem is that
> if
> outlook is running i am getting the same RCW error for object "explorer"
> as
> long as the close event fires. In this case senario :
> 1. outlook 2007 is running
> 2. my program runs and gets a reference to running outlook using
> getobject.
> 3. user closes outlook
> 4. close event fires,
> 5. vs2008 seems to be busy for a few seconds
> 6. A small blue dot appears at breakpoint "the process or thread has
> changed since last step"
> 7. i catch RCW error
> This is all the code i use:

> Imports Microsoft.Office.Interop
> Imports System
> Imports System.IO
> Public Class Form1

> Private WithEvents o As Outlook.Application = Nothing

> Private ns As Outlook.NameSpace = Nothing

> Private WithEvents explorer As Outlook.Explorer

> Private omFolder As Outlook.MAPIFolder = Nothing

> Private Declare Function FindWindow Lib "user32" Alias _
> "FindWindowA" (ByVal lpClassName As String, _
> ByVal lpWindowName As IntPtr) As IntPtr

> Public Sub New1()
> If detectOutlook() Then

> o = GetObject(, "Outlook.Application")
> ns = o.GetNamespace("MAPI") ' get namespace
> ns.Logon("", "", False, False) 'log into Outlook session
> Else
> o = New Outlook.Application
> ns = o.GetNamespace("MAPI") ' get namespace
> ns.Logon("", "", False, True) 'log into new Outlook session
> End If

> Try
> omFolder =
> ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> explorer()
> explorer = o.ActiveExplorer
> Catch ex1 As Exception
> Err.Clear()
> End Try

> End Sub
> Private Function detectOutlook() As Boolean
> detectOutlook = False
> Dim hwnd As IntPtr
> hwnd = FindWindow("rctrl_renwnd32", IntPtr.Zero)
> If hwnd <> IntPtr.Zero Then Return True
> End Function
> Private Sub ex_Close() Handles explorer.Close
> 'this works fine if i create outlook application using o = New
> Outlook.Application
> Try
> If Not o.Explorers Is Nothing Then
> If o.Explorers.Count = 0 Then
> If Not omFolder Is Nothing Then
> Marshal.ReleaseComObject(omFolder)
> If Not explorer Is Nothing Then
> Marshal.ReleaseComObject(explorer)
> explorer = Nothing
> If Not ns Is Nothing Then
> Marshal.ReleaseComObject(ns)
> If Not o Is Nothing Then
> Marshal.ReleaseComObject(o)

> omFolder = Nothing
> ns = Nothing
> o = Nothing
> GC.Collect()
> GC.WaitForPendingFinalizers()
> GC.Collect()
> GC.WaitForPendingFinalizers()
> End If
> End If
> End If
> Catch ex1 As Exception
> Err.Clear() 'Here i catch RCW error
> End Try

> End Sub
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button1.Click
> New1()
> End Sub
> End Class
 
K

kostas

Hello again Ken, i translated your code in vb.net skipping the outlook

detection algorithm. i used Marshal.GetActiveObject("Outlook.Application") to

get running outlook and then assign o.session to namespace. The code now

looks like this :

Public Sub New1()

If detectOutlook() Then

o = Marshal.GetActiveObject("Outlook.Application")

ns = o.Session

Else

o = New Outlook.Application

ns = o.GetNamespace("MAPI") ' get namespace

ns.Logon("", "", False, True) 'log into new Outlook session

End If

Try

omFolder =

ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder

If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show

explorer()

explorer = o.ActiveExplorer

Catch ex1 As Exception

Err.Clear()

End Try

End Sub

The RCW error in explorer.close event still occurs. All objects seem to be

unaffected except explorer object which produces the RCW error. I have also

tried to change registry to change shutdown event to preSP2 behavior but

still nothing.

Maybe somehow this happens because i declare explorer object withevents and

then it gets its reference from o.activeExplorer. I can't figure it out why

is this happening only when i use running outlook application and not when i

create outlook app.
wrote:


> I don't use VB.NET very often, but I don't really use GetObject() at all in
> managed code. I'm not saying it doesn't work or has bad effects, I just
> don't use it. What I do use when I want to get an Outlook instance in a
> standalone program is something like this, which is a C# procedure. It
> shouldn't be hard to translate to VB.NET though:

> private void InstantiateOutlook()

> {

> try

> {

> System.Diagnostics.Process[] processes =
> System.Diagnostics.Process.GetProcessesByName("OUTLOOK");

> int collCount = processes.Length;

> if (collCount != 0)

> {

> // Outlook already running, hook into the Outlook instance

> outlookApp = Marshal.GetActiveObject("Outlook.Application") as
> Outlook.Application;

> }

> if (outlookApp != null)

> {

> canQuit = false;

> }

> else

> {

> // Outlook not already running, start it

> outlookApp = new Outlook.Application();

> canQuit = true;

> }

> if (outlookApp != null)

> {

> if (canQuit)

> {

> ns = outlookApp.GetNamespace("MAPI");

> ns.Logon(System.Reflection.Missing.Value,
> System.Reflection.Missing.Value, System.Reflection.Missing.Value,
> System.Reflection.Missing.Value);

> }

> else

> {

> // Outlook was running, just hook into existing Session

> ns = outlookApp.Session;

> }

> }

> }

> catch (System.Exception ex)

> {

> MessageBox.Show(ex.Message);

> }

> }

> And I handle Explorer.Close() as well as Application.Quit() to do my
> shutdowns.

> >

>

> "kostas" <kostas> wrote in message
> news:7203E1F0-26A1-4E15-922C-6C9E1F7BCE41@microsoft.com...
> > Hello again ken and thank you for your precious help. I have created a new
> > project in vs2008 just to make sure that i do not release any objects by
> > mistake. This code runs really well as long as there is no outlook
> > running.
> > the close event fires and i can release all objects. The problem is that
> > if
> > outlook is running i am getting the same RCW error for object "explorer"
> > as
> > long as the close event fires. In this case senario :
> > 1. outlook 2007 is running
> > 2. my program runs and gets a reference to running outlook using
> > getobject.
> > 3. user closes outlook
> > 4. close event fires,
> > 5. vs2008 seems to be busy for a few seconds
> > 6. A small blue dot appears at breakpoint "the process or thread has
> > changed since last step"
> > 7. i catch RCW error
> > This is all the code i use:
> > Imports Microsoft.Office.Interop
> > Imports System
> > Imports System.IO
> > Public Class Form1
> > Private WithEvents o As Outlook.Application = Nothing
> > Private ns As Outlook.NameSpace = Nothing
> > Private WithEvents explorer As Outlook.Explorer
> > Private omFolder As Outlook.MAPIFolder = Nothing
> > Private Declare Function FindWindow Lib "user32" Alias _
> > "FindWindowA" (ByVal lpClassName As String, _
> > ByVal lpWindowName As IntPtr) As IntPtr
> > Public Sub New1()
> > If detectOutlook() Then
> > o = GetObject(, "Outlook.Application")
> > ns = o.GetNamespace("MAPI") ' get namespace
> > ns.Logon("", "", False, False) 'log into Outlook session
> > Else
> > o = New Outlook.Application
> > ns = o.GetNamespace("MAPI") ' get namespace
> > ns.Logon("", "", False, True) 'log into new Outlook session
> > End If
> > Try
> > omFolder =
> > ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> > If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> > explorer()
> > explorer = o.ActiveExplorer
> > Catch ex1 As Exception
> > Err.Clear()
> > End Try
> > End Sub
> > Private Function detectOutlook() As Boolean
> > detectOutlook = False
> > Dim hwnd As IntPtr
> > hwnd = FindWindow("rctrl_renwnd32", IntPtr.Zero)
> > If hwnd <> IntPtr.Zero Then Return True
> > End Function
> > Private Sub ex_Close() Handles explorer.Close
> > 'this works fine if i create outlook application using o = New
> > Outlook.Application
> > Try
> > If Not o.Explorers Is Nothing Then
> > If o.Explorers.Count = 0 Then
> > If Not omFolder Is Nothing Then
> > Marshal.ReleaseComObject(omFolder)
> > If Not explorer Is Nothing Then
> > Marshal.ReleaseComObject(explorer)
> > explorer = Nothing
> > If Not ns Is Nothing Then
> > Marshal.ReleaseComObject(ns)
> > If Not o Is Nothing Then
> > Marshal.ReleaseComObject(o)
> > omFolder = Nothing
> > ns = Nothing
> > o = Nothing
> > GC.Collect()
> > GC.WaitForPendingFinalizers()
> > GC.Collect()
> > GC.WaitForPendingFinalizers()
> > End If
> > End If
> > End If
> > Catch ex1 As Exception
> > Err.Clear() 'Here i catch RCW error
> > End Try
> > End Sub
> > Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> > System.EventArgs) Handles Button1.Click
> > New1()
> > End Sub
> > End Class


> .
>
 
K

Ken Slovak - [MVP - Outlook]

I don't know why you get this when you hook into a running Outlook

application. You can try getting your Explorer object from Explorers(1)

instead of from ActiveExplorer, and I'd certainly test for ActiveExplorer

not being Nothing (null).

Usually you would only get an RCW error if you have already released the

object elsewhere or if your release code runs twice.

I don't think the problem is WithEvents, but you can always comment that out

and instantiate your handler using AddHandler instead and see if that makes

a difference.

"kostas" <kostas> wrote in message

news:220192F9-E9D5-433B-BC06-6E6B9D872702@microsoft.com...
> Hello again Ken, i translated your code in vb.net skipping the outlook
> detection algorithm. i used Marshal.GetActiveObject("Outlook.Application")
> to
> get running outlook and then assign o.session to namespace. The code now
> looks like this :
> Public Sub New1()
> If detectOutlook() Then
> o = Marshal.GetActiveObject("Outlook.Application")
> ns = o.Session
> Else
> o = New Outlook.Application
> ns = o.GetNamespace("MAPI") ' get namespace
> ns.Logon("", "", False, True) 'log into new Outlook session
> End If

> Try
> omFolder =
> ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) 'get folder
> If o.Explorers.Count = 0 Then o.Explorers.Add(omFolder) 'show
> explorer()
> explorer = o.ActiveExplorer
> Catch ex1 As Exception
> Err.Clear()
> End Try

> End Sub

> The RCW error in explorer.close event still occurs. All objects seem to
> be
> unaffected except explorer object which produces the RCW error. I have
> also
> tried to change registry to change shutdown event to preSP2 behavior but
> still nothing.
> Maybe somehow this happens because i declare explorer object withevents
> and
> then it gets its reference from o.activeExplorer. I can't figure it out
> why
> is this happening only when i use running outlook application and not when
> i
> create outlook app.
 
Status
Not open for further replies.
Similar threads
Thread starter Title Forum Replies Date
B Inconsistent handling of message read/unread status by Outlook Using Outlook 3
A How are you handling Outlook.com category issue and syncing Using Outlook.com accounts in Outlook 2
Stig Arvidsson Need a Script for handling moved mail from inbox Using Outlook 3
S Need solution to Outlook mail handling/syncing/mobile situation, please Using Outlook 2
P Handling Multiple eMail Accounts Using Outlook 2
S Need: Date handling in Outlook Macros, either information/documentation Outlook VBA and Custom Forms 1
T Outlook 2003 Custom Form Error Handling Outlook VBA and Custom Forms 8
U Adding multiple menu Items. Problems handling the click events Outlook VBA and Custom Forms 1
C HANDLING ERRORS USING FIND Outlook VBA and Custom Forms 3
bmtjedi Set objApp = Application Not Working in O365-32bit Using Outlook 1
avant-guvnor Outlook.Application now produces error Outlook VBA and Custom Forms 5
C Custom Application Form send Email to Another User Using Outlook 1
N Select Existing BCM Business Contact in C# application Using Outlook 0
S Using "start application" rule action Using Outlook 2
smokiibear windows security mail application not accepting username and password Using Outlook 0
Y VBA - Application Filedialog Hidden Behind Outlook Using Outlook 0
T Synchronize outlook appointments through web application. Using Outlook 1
O Outlook 2010 Stops Working When Accounting Application Tries To Send eMail Using Outlook 4
C MAPI to access a 64 bit Outlook from a 32 bit application; or access via ODBC Using Outlook 0
A turn Outlook into a Drag-and-drop application Outlook Wishlist 2
M VSTO C#: How do I declare an application scope variable? Outlook VBA and Custom Forms 2
E Turn application visibility off Outlook VBA and Custom Forms 2
T Run application from cmd button Outlook VBA and Custom Forms 5
D Outlook 2007 Will Not Send Mail From C# Application Outlook VBA and Custom Forms 7
P Supporting threads in Outlook VBA application Outlook VBA and Custom Forms 1
R vba instantiated internetExplorer.application differs from user la Outlook VBA and Custom Forms 1
K How to disconnect Application.COMAddIns.Item().Object? Outlook VBA and Custom Forms 4
D outlook.exe application error - breakpoint has been reached. fix? BCM (Business Contact Manager) 1
P Drag and Drop mails from Outlook to Clarion6 Application Outlook VBA and Custom Forms 5
J Office application does not match advisory. Why? BCM (Business Contact Manager) 3
D Application.ActiveInspector() is Null on Ribbon Load Outlook VBA and Custom Forms 1
D Application.ActiveInspector().CurrentItem Returns Wrong(Old) Value Outlook VBA and Custom Forms 3
L RE: BCM Office Application Issue BCM (Business Contact Manager) 1
R Can calendar be displayed in another Office application? Outlook VBA and Custom Forms 1
C Outlook email progress window will not quit Using Outlook 1
G Quit event code - 2007 Using Outlook 3
M Search quit Using Outlook 1
J [outlook-users] outlook 2007 Sp2: Error message to quit outlook Using Outlook 9
S Send All emails in Outbox and Quit using VBA Outlook VBA and Custom Forms 3
R Help, Outlook2003 won't quit after call OnDisconnection? Outlook VBA and Custom Forms 3
R Outlook wont .quit Outlook VBA and Custom Forms 4

Similar threads

Top