解决从脚本加载 USE 或 USELSX 错误

resolve loading USE or USELSX error from script

我正在使用 Lotus Notes 6.5.6,有时,当用户尝试执行代理注释时会出现 "loading USE or USELSX module" 错误,因此,我必须进入我的代理所使用的库并重新-保存。之后代理工作。我不知道这个错误的原因,但我正在研究以了解它,同时我必须找到一个解决方案,让用户在我不在场的情况下解决问题。 所以我正在寻找一个允许用户访问库并重新保存它以解决该错误的解决方案。

我尝试这样做:

Dim db As NotesDatabase
Dim session As New NotesSession
Dim doclib As NotesDocument
Dim colllib As NotesNoteCollection
Dim id As String
Set db=session.CurrentDatabase
Set colllib = db.CreateNoteCollection(False)
colllib.SelectScriptLibraries=True
Call colllib.BuildCollection()
Id=colllib.GetFirstNoteId
While Not Id=""     
    Set doclib=db.GetDocumentByID(Id)
    If Not doclib Is Nothing Then
        Call doclib.ComputeWithForm(False,False)
        Call doclib.Save(True,False)
    End If
    id=colllib.GetNextNoteId(Id)
Wend

但是错误没有解决。 我能怎么做 ? 谢谢

为了解决您的问题,您需要重新编译脚本(将其保存在 Designer-Client 中时会自动执行的操作),然后以编程方式对其进行签名(只有使用 C-API).在设计元素上调用 "ComputeWithForm" 不会重新编译脚本。

与其修理不该坏的东西,不如调查这个代理停止的原因运行。

通常发生这种情况,当设计器任务 "merges" 脚本库/代理从不同的模板到一个数据库时。

我很确定,您的代理不再工作的原因是夜间设计师任务。尝试从 "broken" 数据库中取出模板名称或对其进行操作(添加一个 "x" 或其他内容)以便保留信息,但设计器任务未找到相应的模板。这应该可以解决您的问题。

如果你真的不能用这种方法解决问题,那么试试我找到的这段代码 here,把它放在一个代理中,让用户通过另一个代理使用 ag.RunOnServer 调用它(然后它以比用户更多的权限运行:

'LS Recompile: 

Option Public
Option Explicit

%REM
An example of using Notes API calls to recompile LotusScript.

version 1.0
Julian Robichaux
http://www.nsftools.com
%END REM


'** Notes C-API functions
Declare Function OSPathNetConstruct Lib "nnotes.dll" (Byval portName As Integer, _
Byval serverName As String, Byval fileName As String, Byval pathName As String) As Integer

Declare Function NSFDbOpen Lib "nnotes.dll" (Byval dbName As String, hDb As Long) As Integer
Declare Function NSFDbClose Lib "nnotes.dll" (Byval hDb As Long) As Integer

Declare Function NSFNoteLSCompile Lib "nnotes.dll" (Byval hDb As Long, _
Byval hNote As Long, Byval dwFlags As Long) As Integer
Declare Function NSFNoteSign Lib "nnotes.dll" (Byval hNote As Long) As Integer
Declare Function NSFNoteUpdate Lib "nnotes.dll" (Byval hNote As Long, _
Byval flags As Integer) As Integer

Declare Function OSLoadString Lib "nnotes.dll" (Byval hModule As Long, Byval stringCode As Integer, _
Byval retBuffer As String, Byval bufferLength As Integer) As Integer


'================================================================
' Base class for working with Notes databases at the API level
'================================================================
Class APIBaseClass
    Private db As NotesDatabase
    Private hDb As Long
    Private lastError As String


    Public Sub New ()
        '** nothing to instantiate in the base class
    End Sub


    Public Sub Delete ()
        Call CloseDatabase()
    End Sub


    Public Function OpenDatabase (db As NotesDatabase) As Integer
        On Error Goto processError

        If (hDb > 0) Then
            Call CloseDatabase()
        End If

        '** reset the internals
        Set Me.db = db
        lastError = ""

        Dim pathName As String*256
        Dim result As Integer

        '** create a proper network path name with OSPathNetConstruct
        Call OSPathNetConstruct(0, db.Server, db.FilePath, pathName)

        '** open the database and get a handle with NSFDbOpen
        result = NSFDbOpen(pathName, hDb)
        If result = 0 Then
            OpenDatabase = True
        Else
            Call SetLastError("Cannot open database " & db.FilePath & " on server " & db.Server, result)
        End If

        Exit Function

processError:
        Call SetLastError("Error opening database", 0)
        Exit Function

    End Function


    Public Sub CloseDatabase ()
        On Error Resume Next

        If (hDb > 0) Then
            Call NSFDbClose(hDb)
        End If

        Set db = Nothing
        hDb = 0
        lastError = ""
    End Sub


    Private Function SetLastError (errText As String, apiResultCode As Integer) As String
        If (apiResultCode <> 0) Then
            LastError = "API Error " & apiResultCode & ": " & GetAPIError(apiResultCode)
        Elseif (Err > 0) Then
            LastError = "Notes Error " & Err & ": " & Error$
        Else
            LastError = ""
        End If

        If (Len(errText) > 0) Then
            LastError = errText & ". " & LastError
        End If
    End Function


    Public Function GetLastError () As String
        GetLastError = LastError
    End Function


    Public Function GetAPIError (errorCode As Integer) As String
        Dim errorString As String*256
        Dim returnErrorString As String
        Dim resultStringLength As Long
        Dim errorCodeTranslated As Integer

        Const ERR_MASK = &H3fff
        Const PKG_MASK = &H3f00
        Const ERRNUM_MASK = &H00ff

        '** mask off the top 2 bits of the errorCode that was returned; this is
        '** what the ERR macro in the API does
        errorCodeTranslated = (errorCode And ERR_MASK)

        '** get the error code translation using the OSLoadString API function
        resultStringLength = OSLoadString(0, errorCodeTranslated, errorString, Len(errorString) - 1)

        '** strip off the null-termination on the string before you return it
        If (Instr(errorString, Chr(0)) > 0) Then
            returnErrorString = Left$(errorString, Instr(errorString, Chr(0)) - 1)
        Else
            returnErrorString = errorString
        End If

        GetAPIError = returnErrorString

    End Function

End Class


'================================================================
' Special subclass for recompiling a note/doc in a database
'================================================================
Class LotusScriptRecompiler As APIBaseClass

    Public Function RecompileLSByNoteID (noteID As String) As Integer
        On Error Goto processError

        If (db Is Nothing) Then
            Call SetLastError("Database is not open", 0)
            Exit Function
        End If

        Dim doc As NotesDocument
        Set doc = db.GetDocumentByID(noteID)
        RecompileLSByNoteID = RecompileLS(doc)
        Exit Function

processError:
        Call SetLastError("Error recompiling LotusScript for " & noteID, 0)
        Exit Function

    End Function


    Public Function RecompileLSByUNID (unid As String) As Integer
        On Error Goto processError

        If (db Is Nothing) Then
            Call SetLastError("Database is not open", 0)
            Exit Function
        End If

        Dim doc As NotesDocument
        Set doc = db.GetDocumentByUNID(unid)
        RecompileLSByUNID = RecompileLS(doc)
        Exit Function

processError:
        Call SetLastError("Error recompiling LotusScript for " & unid, 0)
        Exit Function

    End Function


    Public Function RecompileLS (doc As NotesDocument) As Integer
        On Error Goto processError

        Dim hNote As Long
        Dim unid As String
        Dim result As Integer

        If (hDb = 0) Then
            Call SetLastError("Database is not open", 0)
            Exit Function
        Elseif (doc Is Nothing) Then
            Call SetLastError("Invalid document reference", 0)
            Exit Function
        End If

        '** super-special-secret way of getting an API handle to a NotesDocument
        hNote = doc.Handle
        unid = doc.UniversalID

        '** first, we compile the note
        result = NSFNoteLSCompile(hDb, hNote, 0)
        If (result <> 0) Then
            Call SetLastError("Cannot compile LotusScript for " & GetTitle(doc), result)
            Exit Function
        End If

        '** then we sign it
        result = NSFNoteSign(hNote)
        If (result <> 0) Then
            Call SetLastError("Cannot sign " & GetTitle(doc), result)
            Exit Function
        End If

        '** then we save it
        result = NSFNoteUpdate(hNote, 0)
        If (result <> 0) Then
            Call SetLastError("Cannot save " & GetTitle(doc), result)
            Exit Function
        End If

        '** update the in-memory reference to the object
        Delete doc
        Set doc = db.GetDocumentByUNID(unid)

        '** a little trick to avoid this message on recompiled forms:
        '** This document has been altered since the last time it was signed! Intentional tampering may have occurred.
        Call doc.Sign()
        Call doc.Save(True, False)

        lastError = ""
        RecompileLS = True
        Exit Function

processError:
        Call SetLastError("Error recompiling LotusScript for " & GetTitle(doc), 0)
        Exit Function

    End Function


    Public Function GetTitle (doc As NotesDocument) As String
        On Error Resume Next
        If (doc Is Nothing) Then
            Exit Function
        End If

        Dim title As String
        title = doc.~$Title(0)
        If (Instr(title, "|") > 0) Then
            title = Strleft(title, "|")
        End If

        If (title = "") Then
            title = "(untitled)"
        End If

        GetTitle = |"| & title & |"|
    End Function
End Class



Sub Initialize
    '** As a test, let's recompile all the agents, script libraries, and forms
    '** in this database
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Dim nc As NotesNoteCollection
    Dim recompiler As New LotusScriptRecompiler
    Dim noteID As String

    '** create our recompiler object
    Set db = session.CurrentDatabase
    Call recompiler.OpenDatabase(db)
    If (recompiler.GetLastError <> "") Then
        Print recompiler.GetLastError
        Exit Sub
    End If

    '** compile the script libraries first (note that this will NOT build a
    '** dependency tree -- rather, we'll try to brute-force around the 
    '** dependencies by recompiling until either (A) there are no errors,
    '** or (B) the number of errors we get is the same as we got last time)
    Dim errCount As Integer, lastCount As Integer
    Set nc = db.CreateNoteCollection(False)
    nc.SelectScriptLibraries = True
    Call nc.BuildCollection

    Print "SCRIPT LIBRARIES"
    Do
        lastCount = errCount
        errCount = 0

        noteID = nc.GetFirstNoteId
        Do Until (noteID = "")
            If recompiler.RecompileLSByNoteID(noteID) Then
                Print "Successfully recompiled " & _
                recompiler.GetTitle(db.GetDocumentByID(noteID))
            Else
                Print recompiler.GetLastError
                errCount = errCount + 1
            End If

            noteID = nc.GetNextNoteId(noteID)
        Loop
    Loop Until ( (errCount = 0) Or (errCount = lastCount) )

    '** then compile everything else
    Set nc = db.CreateNoteCollection(False)
    nc.SelectAgents = True
    nc.SelectForms = True
    Call nc.BuildCollection

    Print "FORMS AND AGENTS"
    noteID = nc.GetFirstNoteId
    Do Until (noteID = "")
        If recompiler.RecompileLSByNoteID(noteID) Then
            Print "Successfully recompiled " & _
            recompiler.GetTitle(db.GetDocumentByID(noteID))
        Else
            Print recompiler.GetLastError
        End If

        noteID = nc.GetNextNoteId(noteID)
    Loop

    Call recompiler.CloseDatabase()
    Print "All done"
End Sub