16

In particular, I have to extract all the messages and attachments from Lotus Notes files in the fastest and most reliable way. Another point that may be relevant is that I need to do this from a secondary thread.

Edit

Thanks for the answers - both of which are good. I should provide more background information.

We currently have a WinForms application with a background thread using the Notes COM API.

However it seems to be unstable. (Of course it may be we are doing something wrong.) For example, we have found we have to preinitialize the Notes session on the main thread or else the call to session.CreateDXLExporter() on the background thread throws an exception.

Phil Haselden
  • 2,876
  • 3
  • 30
  • 25

10 Answers10

6

I really do hate that NotesSession COM object.

You cannot use it in another thread than the thread it was initialized. Threads in .NET are fibers, the real underlying thread may change at any time.

So I suggest using it this way, in a using block :

Imports Domino
Imports System.Threading

Public Class AffinitedSession
    Implements IDisposable

    Private _session As NotesSession
    Public Sub New(ByVal pass As String)
        Thread.BeginThreadAffinity()
        _session = New NotesSession()
        _session.Initialize(pass)
    End Sub

    Public ReadOnly Property NotesSession() As NotesSession
        Get
            Return _session
        End Get
    End Property

    Private disposedValue As Boolean = False        ' To detect redundant calls

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: free other state (managed objects).
            End If

            ' TODO: free your own state (unmanaged objects).
            ' TODO: set large fields to null.
            _session = Nothing
            Thread.EndThreadAffinity()
        End If
        Me.disposedValue = True
    End Sub

#Region " IDisposable Support "
    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class

Notice the Thread.BeginThreadAffinity() and the Thread.EndThreadAffinity()

Those are your friends.

Cheers !

Alex Rouillard
  • 777
  • 8
  • 9
  • Very interesting answer Alex. I will look into this further. Thanks. BTW, I haven't found anything that states that .Net threads are fibres, though I have seen some doco saying that we shouldn't assume .Net threads have a 1-to-1 mapping to unmanaged OS threads. – Phil Haselden Jul 21 '10 at 02:07
  • Those are not *real* fibers like Python or Ruby, those are managed threads. That is why the underlying OS thread can change at any time. – Alex Rouillard Jul 21 '10 at 14:52
3

An Lotus Notes COM Api Reference can be found here

To get a Notes Session (The starting point) in VB.Net you can use:

Dim oSess As Object = Nothing
oSess = CreateObject("Notes.NotesSession")

I normally program in C#, for operating with COM I prefer VB.Net

It is better to access all COM servers from the same thread, unless you are certain that is will not cause any trouble.

GvS
  • 52,015
  • 16
  • 101
  • 139
2

Take a look at NotesSQL:

http://www.ibm.com/developerworks/lotus/products/notesdomino/notessql/

Joshua Turner
  • 1,029
  • 2
  • 10
  • 16
  • Any idea if this can be used to get items out in a "native" format such as .dxl (without having to produce the XML ourselves)? – Phil Haselden Sep 18 '08 at 05:04
2

If you have a Domino / Lotus Notes client installed on the same machine, you can use COM. Just do a Google search on 'Accessing the Domino Objects through COM' and you'll find the Domino Designer help entry for just about any version of Domino.

You can also access Domino via the C API, but wouldn't recommend it. Very messy. You also still need the Domino / Lotus Notes client installed.

If you do not have Domino / Lotus Notes client installed on the same machine and the Domino server is running http, you could also do it via http. This will not be nearly as fast. You would also probably want some custom http views setup on the Domino server to make your life easier.

Jeff Bonnes
  • 1,128
  • 6
  • 6
2

You could create a Domino web service using Java or LotusScript. Then use C# to access the web service.

I've only done this once, to read data out of an Lotus Notes db into a .NET app running on another machine.

Writing and testing simple Web services http://www.ibm.com/developerworks/lotus/library/web-services2/

when i find some time I will write a complete example :-)

Eric Labashosky
  • 29,484
  • 14
  • 39
  • 32
  • Hi Eric... Right now I am using interop but thinking to switch to Web Service. To use interop one needs to install Lotus Notes on that machine. Is it the same case with Web Service? Thanks – om471987 Apr 24 '12 at 09:53
  • No, you call a web service on the Domino server, and that functionality is built-in as of Notes 7.0, I beliveve. So you don't need the Notes client installed locally, from where you are calling the web service. – Karl-Henry Martinsson Nov 26 '12 at 15:26
1

I worked on a Notes plugin for several months a little while back, and yes, the API can be maddening. However, I was able to get it to work so I could access all the Notes information using a C# application (actually, since I was writing a plugin, I had Notes call out to the C# app through a C++ bridge that it registered in a startup .ini file). Certain methods that they document in their API don't actually work though, so a lot of testing is required. Sometimes you have to do some code gymnastics...

Sam Schutte
  • 6,666
  • 6
  • 44
  • 54
1

I know this thread is old, but I've worked a lot with the Domino API and the typical Notes LotusScript objects via the Domino COM API.

The problem with the Domino API is that its memory management via COM is horrible (if using the API in C#, or VB, etc.), and it will cause memory leaks and eventually cause the whole API and the Notes client to crash (even if you don't have the client open, you will not be able to start it after the API crashes without restarting your computer, or calling "nsd -kill"). Fun.

I've found that using the Notes C API within C# via P/Invoke, you can better manage the memory resources so that the API doesn't cause horrible memory leaks and crashes. I wrote a partial wrapper in C#, using P/Invoke, that accesses the Notes C API from the notes.dll. My use of it has nothing to do with trying to work within a Domino environment, but to make use of the Notes assembly to have access to NSF files to extract DXL information within a C# environment. Obviously, you would need to have the Notes client installed to have access to the notes.dll and the C API. But my C# wrapper of the Notes C API works great and is more stable than the Domino COM API that is provided when you install the Notes client.

The classes that I've implemented in C# (that I've only needed) from the Notes C API are:

NotesSession (as NotesRuntime) NotesDatabase NotesNote NotesItem NotesDXLExporter NotesNoteCollection

As well as some other interim classes, enums, and structs to handle the translation from the C API into C#.

The classes I've implemented thus far have served the purposes that I've needed from the Notes C API. They can definitely be expanded upon, but I didn't try to encapsulate the entire API within the C# P/Invoke wrapper. I also had to create handlers for dealing with OLE embedded objects that may be stored within Notes documents, and getting the stored data out of those OLE objects, using Windows IStorage objects.

Note: I can provide some samples later (I have to rename namespaces and generalize the code, due to proprietary reasons), but I created the C# wrapper classes by using the "Lotus C API Notes/Domino 8.5.2 Reference" NSF that is provided by IBM/Lotus (as a downloadable NSF). Using the C definitions and class references, I could translate those to C# P/Invoke calls and wrap them into friendlier C# classes, that then behaved more like LotusScript class calls, but within C#, and the implemented classes manage and dispose of their memory so that the whole thing doesn't crash after you've accessed hundreds of thousands of documents from a C# program. :)

  • Let me know if you want sources of what has been described above. I can't attach them here, nor do I want to provide a public FTP address. – Brien Halstead Apr 09 '16 at 13:31
  • Thanks @Brien-Halstead. I don't have a current need for the code but it would be good to have for future reference. Feel free to DM me on twitter (see my profile). – Phil Haselden Apr 11 '16 at 01:17
1

Back in the day I would have recommended N2N from Proposion, but that product has gone since Quest acquired Proposion.

That said, Proposion was proof that you can wrap the Notes API in a set of .Net classes safely. You can find some info on that in Bob Balaban's blog.

Peter T. LaComb Jr.
  • 2,935
  • 2
  • 29
  • 44
0

I would personally do this native in Notes in either LotusScript or Java. You can do a scheduled agent in Notes much easier than a service in C#.

Martin Murphy
  • 1,775
  • 2
  • 16
  • 24
0

I personally quite like Domino wrapped .NET assembly for COM API. When you develop your C# code you almost can imagine your dreams about a proper Notes IDE became true. But it has some drawbacks like for the version 6.5 (I haven't tried newer) you get your application crashes in many cases when the LotusScript code returns type mismatch for the parameter. But this is due to COM limitations of course.

At the same time the wrapper doesn't allow working with NotesUI classes. However I used reflections from very old Notes COM API examples to call NotesUI classes and it worked. It was handy when I developed an Outlook plug-in that required interaction with Notes client UI. I managed to create a simple wrapper for UI classes too.

Alexey Zimarev
  • 17,944
  • 2
  • 55
  • 83