CoSign SAPI - 有没有办法在不关闭文档的情况下使用Word VBA和SAPI签署打开的Microsoft Word文档?

时间:2015-04-15 00:13:13

标签: cosign-api

下面的Word VBA代码使用CoSign SAPI签署在Word中打开的包含CoSign签名字段的Microsoft Word文档。此代码成功执行并签署Word文档。 VBA代码必须在使用SAPI签名之前关闭Word文档,然后在签名后重新打开文档(请参阅下面的代码用星号)。当用户签署文档时,需要执行自定义VBA代码。

  1. 有没有办法修改VBA代码以签署Word文档而无需先关闭Word文档?

  2. 右键单击Word中的CoSign签名字段并单击“签名”时,是否有办法拦截VBA代码中的CoSign Sign事件?

  3. ' ** VBA for Word Code使用CoSign SAPI签署Word文档

     Public Sub CoSign_SignDocument()
        Const SAPI_OK As Integer = 0
        Const SUB_NAME As String = "coSign_SignDocument"
    
        Dim i As Integer
        Dim rc As Integer
        Dim SAPI As SAPICrypt
        Dim sesHandle As sesHandle
        Dim SFS As SigFieldSettings
        Dim SFI As SigFieldInfo
        Dim SFH As SigFieldHandle
    
        Set SFI = New SigFieldInfo
        Set SFS = New SigFieldSettings
        Set sesHandle = Nothing
        Set SAPI = New SAPICrypt
    
        'Custom Values
        Dim filePath As String  'file to sign
        Dim username As String  'CoSign account username
        Dim FH As FileHandle
        Dim password As String  'CoSign account password
        Dim domain As String    'CoSign account domain
        Dim flags As Integer
        Dim FieldName As String
    
        'Assign values to the variables declared above
        username = "{signer_username}"    'CoSign account username
        password = "{signer_password}"    'CoSign account password
        domain = ""                       'CoSign account domain
        flags = 0
    
        On Error GoTo CatchExecption
    
        'Initialize SAPI library
        rc = SAPI.Init
        If rc <> SAPI_OK Then
            Err.Raise vbObjectError + 1001, MODULE_NAME + ":" + SUB_NAME, _
                "Failed to initialize SAPI " + Str(rc) + " " + Err.Description
        End If
    
        'Acquire SAPI session handle
        rc = SAPI.HandleAcquire(sesHandle)
        If rc <> SAPI_OK Then
            Err.Raise vbObjectError + 1001, MODULE_NAME + ":" + SUB_NAME, _
                "Failed in SAPIHandleAcquire() " + Str(rc) + " " +
    Err.Description
        End If
    
        'Personalize SAPI Session
        SAPI.Logon sesHandle, username, domain, password
        If rc <> SAPI_OK Then
            Err.Raise vbObjectError + 1001, MODULE_NAME + ":" + SUB_NAME, _
                "Failed to authenticate user " + Str(rc) + " " + Err.Description
        End If
    
        Dim fileType As SAPI_ENUM_FILE_TYPE
        fileType = SAPI_ENUM_FILE_TYPE.SAPI_ENUM_FILE_WORD
    
    
    '**** Close the Word Document before processing with SAPI functions
        filePath = ActiveDocument.FullName
        ActiveDocument.Close SaveChanges:=False
        FieldName = "Secretary"
    
        'Initialize enumerating signature fields
        Dim SFC As SAPIContext
        Set SFC = New SAPIContext
        Dim SFNum As Long
        Dim SFFlags As Integer
        rc = SAPI.SignatureFieldEnumInit(sesHandle, SFC, fileType, filePath, 0, SFNum)
        If rc <> 0 Then
            Err.Raise vbObjectError + 1001, MODULE_NAME, _
                "Failed in SignatureFieldEnumInit() " + Str(rc) + " " + Err.Description
        End If
    
        Dim isFound As Boolean
        For i = 1 To SFNum
    
            'Get Next field's handle
            rc = SAPI.SignatureFieldEnumCont(sesHandle, SFC, SFH)
            If rc <> 0 Then
                SAPI.ContextRelease SFC
                SAPI.Logoff sesHandle
                SAPI.HandleRelease sesHandle
                Err.Raise vbObjectError + 1001, MODULE_NAME, _
                    "Failed in SignatureFieldEnumCont() " + Str(rc) + " " + Err.Description
            End If
    
            'Retrieve Signature Field's info
            rc = SAPI.SignatureFieldInfoGet(sesHandle, SFH, SFS, SFI)
            If rc <> 0 Then
                SAPI.HandleRelease SFH
                SAPI.ContextRelease SFC
                SAPI.Logoff sesHandle
                SAPI.HandleRelease sesHandle
                Err.Raise vbObjectError + 1001, MODULE_NAME, _
                    "Failed in SAPI.SignatureFieldInfoGet() " + Str(rc) + " " + Err.Description
            End If
    
            'Check that the field we've found is not signed. If Signed - just skip it.
            If SFI.IsSigned <> 0 Then
                GoTo NextLoop
            End If
    
            If SFS.Name = FieldName Then
                SAPI.ContextRelease SFC
                isFound = True
                Exit For
            End If
    
            'Release handle of irrelevant signature field
            SAPI.HandleRelease SFH
    NextLoop:
        Next i
    
        If Not isFound Then
            SAPI.ContextRelease SFC
            SAPI.Logoff sesHandle
            SAPI.HandleRelease sesHandle
            Err.Raise vbObjectError + 1001, MODULE_NAME, _
                "The file doesn't contain any signature field named: " + FieldName + " " + Err.Description
        End If
    
        'Sign signature field
        rc = SAPI.SignatureFieldSignEx(sesHandle, SFH, 0, "")
        If rc <> 0 Then
            Err.Raise vbObjectError + 1001, MODULE_NAME, _
                "Failed in SignatureFieldSign() " + Str(rc) + " " + Err.Description
        End If
    
    '***** Re-open the Word document after signing with SAPI 
        Dim wd As Word.Document
        Set wd = Word.Documents.Open(FileName:=filePath)
        wd.Activate
        Set wd = Nothing
        GoTo Finally
    
    CatchExecption:
        MsgBox "Error: " + Err.Description
    
    Finally:
        On Error GoTo errProc
        If Not sesHandle Is Nothing Then
            SAPI.Logoff sesHandle        'Release user context
            SAPI.HandleRelease sesHandle 'Release session handle
        End If
    
        Exit Sub
    
    errProc:
       MsgBox "Error in coSign_SignDocument Routine. " & Err.Description
    End Sub
    

0 个答案:

没有答案