Ben Langhinrichs

April, 2004
SMTWTFS
    01 02 03
04 05 06 07 08 09 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

Search the weblog





























Genii Weblog


Civility in critiquing the ideas of others is no vice. Rudeness in defending your own ideas is no virtue.


Fri 30 Apr 2004, 01:11 AM
I must admit I was astonished when Rocky called me up to say that because you can't export to MS Word in Notes 6, his client was going to use our Midas Rich Text LSX to export to MS Word.  Now, I wasn't surprised that he would think to use Midas, as we have lots of customers who use it for this purpose.  I wasn't surprised that Rocky called me, because he calls me quite often, and not infrequently it is about using Midas for a customer.  What surprised me was the news that Lotus Notes 6.x doesn't even have MS Word as an option when exporting from Notes 6.  Not even the traditional "Microsoft Word 6.0" which they had in R5.

What the heck?  I started looking, and came across this technoteExport Options in User Interface and the @Command FileExport Are not Available or Result in an Error, which shows that the only exports supported by the File Export command are:
  • ASCII Text
  • CGM Image
  • Microsoft RTF
  • TIFF 5.0 Image


which seems to me a pretty short list.  In addition, it says that you can't really use any of the other documented export types for @Command([FileExport]; ...) because they will all give errors.

Now, I like the fact that people buy Midas to export to MS Word, I really do, but I am truly embarrassed that you would have to.  This is 2004, and IBM has taken away the ability to export to anything, even MS Word 6.0.  Here is my favorite excerpt from the technote
Workaround:
In some cases the 'Microsoft RTF' export option may suffice as a substitute type if the target application also has a matching import option. Beyond that, if the desired filter does not exist then use a Notes 5.x Client to perform the export.

I am speechless.  OK, not entirely speechless.  I have just enough voice left to encourage you to check out our sample database Export to MS Word to see that it is possible to have a high quality export to MS Word, even one that works with MS Word 97/2000 and beyond.  (If you have tried it with Midas Version 3.20a, try again once Midas Version 3.30 is out, as both the export and the sample are improved and easier)

Think it won't make much difference?  Look at the four screen shots below.  The first is from Notes 6.0.2.  The second is the same document exported to Microsoft RTF.  The third is the same document exported to MS Word using the R5 export DLL (which you can actually call using Midas' Export method, if you like, even in ND6).  The fourth is the same document exported using Midas 3.30 and the new sample db.  I just took a piece of each for size reasons, but if you try the sample out, you can see what I mean with the whole document.  (Don't forget that you will need an evaluation license for Midas).

Notes version of the document


Microsoft RTF version of the document


Microsoft Word 6.0 (R5) export


Midas Rich Text LSX Version 3.30 export

Copyright © 2004 Genii Software Ltd.

Thu 29 Apr 2004, 01:20 PM
The title is almost the same, but this post shows the same logic as the one before, but using @Midas Formulas 3.30 instead.  Compare the two and see what you think.

pathName := @Prompt([OkCancelEdit]; "Graphic Pathname""Enter the full pathname for the graphics file:");
fileName := @RightBack(pathName; "\\");
@DbCommand("Midas":"NoCache""CreateImageResource"; ""; fileName; pathName);

Sheesh!  It makes the 32 lines of the Midas Rich Text LSX version look long.  Granted, the live version has some error checking and stuff, but it almost makes you wonder why IBM can't come up with this stuff.  Anyway, I just wanted to let you know I was still here... still testing.  I should come up for air soon.

Copyright © 2004 Genii Software Ltd.

Thu 29 Apr 2004, 01:19 AM
While working on a new sample to be distributed with Midas version 3.30, I created this code for creating and modifying image resources with Midas Version 3.30.  It has gotten has gotten very simple.  Here is the whole agent for either creating or modifying an image resource:

Sub Initialize
   ' *** Domino back-end class objects
   Dim session As New NotesSession
   Dim db As NotesDatabase
   
   ' *** Midas back-end class objects
   Dim rtSession As New GeniiSession
   Dim rtitem As New GeniiRTItem
   
   ' *** Miscellaneous processing variables
   Dim fileName As String
   Dim pathName As String
   Dim pos As Integer
   
   Set db = session.CurrentDatabase
   
   pathName$ = Inputbox$("Enter the full pathname for the graphics file:", "Graphic Pathname", "")
   If Len(pathName) =Then Exit Sub
   
   fileName = pathName
   pos = Instr(fileName, "\")
   While pos > 0
      fileName = Mid$(fileName, pos+1, Len(fileName)-pos)
      pos = Instr(fileName, "\")
   Wend
   
   Set rtitem = rtSession.CreateImageResource(db.Server, db.FilePath, fileName, pathName)
   rtitem.Save
End Sub

By default, the CreateImageResource will overwrite the existing image resource, so this will either create or update the image resource.  Pretty simple, eh?

Copyright © 2004 Genii Software Ltd.

Wed 28 Apr 2004, 05:41 PM
I think I need a large sign on my website, on my phone, perhaps even hanging in the air over my head:



Sorry folks if I am ignoring your plaintive cries, but I am trying to get Midas 3.30 out the door, and @Midas Formulas 3.30 (Gold) out shortly after that.  Forgive me if I am a bit delayed in responding...

Copyright © 2004 Genii Software Ltd.

Tue 27 Apr 2004, 10:43 PM
Sparked by some questions about my earlier post, I have done some additional investigation, and noticed that others have made the same dumb assumption I have when investigating Lsi_info and its possible parameters:

For i = 1 to 255
  Print "Lsi_info(" & i & ")=" & Lsi_info(i)
Next i

Look familiar?  On codestore.net, Jake had this similar code:
For i=0 To 255
Print Cstr(i) & "=" & Lsi_info(i) & "<BR>"
Next

Unfortunately it's almost impossible to speculate on the meaning of each of the variables, so was near useless...
and I have seen several others with the same basic code.  On a whim today, I changed this to go up to 32760.  While there was nothing after 442, there were several interesting values after 255, incliding True and False values.  The complete list for that one run I made is at the bottom of this post, but here is what I need from readers.  Take the code:

Dim vals(500) as String
For i = 1 to 500
  vals(500) = Cstr(Lsi_info(i))
Next i

or something similar and run it in various places.  You may or may not want to ignore the blank or zero entries.  If I get a few samples from people running on a Mac or on a server under Linux or in a scheduled agent vs. a manual agent, we may be able to determine what a few more of these mean.  If  you will help, I'll be happy to maintain a more definitive list.  Anybody willing?  Please send results to  so I can put them together in a single table.

The complete list of non-zero, non-blank items
Lsi_info(1)='28'
Lsi_info(2)='INITIALIZE'
Lsi_info(3)='*1BEC110'
Lsi_info(4)='14901208'
Lsi_info(5)='15817068'
Lsi_info(6)='5.0.0.06'
Lsi_info(7)='24'
Lsi_info(8)='40637988'
Lsi_info(9)='en'
Lsi_info(11)='28'
Lsi_info(12)='INITIALIZE'
Lsi_info(13)='*1BEC110'
Lsi_info(14)='*1BEC110,INITIALIZE,17 '
Lsi_info(16)='15817164'
Lsi_info(17)='15816940'
Lsi_info(18)='15817052'
Lsi_info(19)='15817052'
Lsi_info(20)='15817132'
Lsi_info(30)='4'
Lsi_info(31)='4'
Lsi_info(32)='4'
Lsi_info(33)='4'
Lsi_info(50)='1146436'
Lsi_info(51)='1317169'
Lsi_info(52)='1487'
Lsi_info(98)='1000'
Lsi_info(99)='29981576'
Lsi_info(110)='170716'
Lsi_info(111)='186652'
Lsi_info(112)='16'
Lsi_info(113)='170716'
Lsi_info(114)='752'
Lsi_info(115)='12288'
Lsi_info(116)='18'
Lsi_info(117)='752'
Lsi_info(119)='4096'
Lsi_info(123)='4096'
Lsi_info(126)='931048'
Lsi_info(127)='1015829'
Lsi_info(128)='420'
Lsi_info(129)='931048'
Lsi_info(130)='664'
Lsi_info(131)='4096'
Lsi_info(132)='10'
Lsi_info(133)='664'
Lsi_info(201)='54529'
Lsi_info(202)='54552'
Lsi_info(203)='54590'
Lsi_info(204)='54618'
Lsi_info(205)='54648'
Lsi_info(206)='54656'
Lsi_info(207)='54683'
Lsi_info(208)='54711'
Lsi_info(209)='54728'
Lsi_info(400)='-441381'
Lsi_info(403)='4'
Lsi_info(404)='False'
Lsi_info(405)='False'
Lsi_info(406)='False'
Lsi_info(407)='False'
Lsi_info(408)='202'
Lsi_info(409)='2147483584'
Lsi_info(410)='True'
Lsi_info(411)='2000'
Lsi_info(412)='50'
Lsi_info(419)='4'
Lsi_info(420)='17'
Lsi_info(421)='INITIALIZE'
Lsi_info(422)='60'
Lsi_info(430)='17'
Lsi_info(431)='INITIALIZE'
Lsi_info(432)='60'
Lsi_info(440)='W32I'
Lsi_info(441)='W32I'
Lsi_info(442)='5'

Copyright © 2004 Genii Software Ltd.

Tue 27 Apr 2004, 02:45 PM
While it is not a well kept secret, the undocumented Lsi_info function in LotusScript has secrets within secrets.  There is actually a file called LSPRCVAL.LSS in your Notes directory which lists a number of constants for Lsi_info (see the bottom of this post for the 6.0.2 version), but besides these documented constants for the undocumented function, there are undocumented constants.  I am going to concentrate on three that help significantly when tracking memory loss.  This is an issue that is near and dear to my heart since I develop C/C++ extensions and LSXs, and while this may shock you, sometimes memory leaks.   Eeek!  These functions are very helpful when testing our Midas Rich Text LSX, as well as other LSXs, to ensure that memory is not leaking, but even for non-API developers, these are very helpful for determining whether Notes is not letting go of memory for one reason or another.

"So", some bright soul is sure to say, "aren't these just the constants for GetThreadInfo?"

Well, yes they are, but Lsi_info allows values that GetThreadInfo doesn't, and also works in any previous version of Notes, which GetThreadInfo doesn't either.  For these reasons, I use the Lsi_info function.

My agent
The simple agent I tend to use is below saves the agent name and three values:

LSI_Info(50) returns the LotusScript memory allocated. 
LSI_Info(51) returns the LotusScript memory allocated from the OS. 
LSI_Info(52) returns the LotusScript blocks used. 

Sub Initialize
   DimAs New NotesSession
   Dim agent As NotesAgent
   Dim db As NotesDatabase
   Dim doc As NotesDocument
   
   Set db=s.CurrentDatabase
   Set agent = s.CurrentAgent
   Set doc = New NotesDocument(db)
   doc.Form = "MemoryLog"
   doc.AgentName = agent.Name
   doc.lsMemory = Lsi_info(50)
   doc.lsMemoryOS = Lsi_info(51)
   doc.lsMemoryBlks = Lsi_info(52)
   Call doc.Save(True, True)
End Sub

My agent simply saves a document with the current values each time it is called.  You could log this instead, or simply compare one to another, but be aware that there is a lot of start up cost to some operations, and there is also a cost to any background processes running, so try this when nothing else is happening and when you control the situation as much as possible.  With LSX issues, or API issues called through LotusScript, the most important number is usually the blocks.  These represent the "handles" used to open a document or allocate a block of memory, and if this value keeps growing, you will eventually die.  The LotusScript memory tends to grow more with pure LotusScript use, and the memory allocated from the OS tells you whether you are taxing the external memory.  

My best advice is, don't sweat the details.  If any of these values keeps growing, you probably have a problem.  If the number of blocks keeps growing, make sure to do explicit deletes of objects and see if that helps.  If the blocks stay the same and memory keeps growing, watch for arrays and lists that are growing uncontrollably.

Additional undocumented codes
LSI_Info(12) Procedure name of call to current procedure (according to this post by Damien Masson)

LSI_Info(14) returns a list of the LS modules called so far. There are three parameters for each module. The first seems to be some code for the script library, the second is the module name, and the third is the last line number executed in the module before the net module was called (according to this post by Peter Presnell)

Documented codes from LSPRCVAL.LSS file
'-----------------------------------------------------------------------------
' File:      lsprcval.lss
' Copyright (c) 1997 Lotus Development Corporation
'
' Description:  Constants for use with the LSITHREADINFO builtin
'
'-----------------------------------------------------------------------------
public const LSI_THREAD_LINE=0
public const LSI_THREAD_PROC=1
public const LSI_THREAD_MODULE=2
public const LSI_THREAD_VERSION=3
public const LSI_THREAD_LANGUAGE=4
public const LSI_THREAD_COUNTRY=5
public const LSI_THREAD_TICKS=6
public const LSI_THREAD_TICKS_PER_SEC=7
public const LSI_THREAD_PROCESS_ID=8
public const LSI_THREAD_TASK_ID=9
public const LSI_THREAD_CALLPROC=10
public const LSI_THREAD_CALLMODULE=11

Copyright © 2004 Genii Software Ltd.