Answered How to offload document generation to pasoe

swip

New Member
Hi,

I'm currently trying to offload the generation of word documents to my pasoe instance.
my start.p runs a asynchronous procedure on the appserver and sends the response to another p file where the document should be opened again.
I've added the AppServer to my developer studio in order to debug the code.
I get the following error:
"Ein Fehler trat auf bei der Erzeugung/Verbindung zu automation Server für: Word.application.~nCoInitialize wurde nicht aufgerufen.~r~nFehler Code: 0x800401f0 file_transfer_apsv/create_file.p (5894)"
I found this kb-article on how to give permissions for com-handle creation but this didn't work either.
The docx file is present in the appservers temp directory.

Is this even possible or have I done some dumb mistake?
Thanks upfront to anyone reading this. :)

start.p
Code:
BLOCK-LEVEL ON ERROR UNDO, THROW.
DEFINE TEMP-TABLE transfer NO-UNDO
    FIELD ptr AS BLOB.

DEFINE VARIABLE connId   AS INTEGER NO-UNDO.
DEFINE VARIABLE res      AS HANDLE  NO-UNDO.
DEFINE VARIABLE req      AS HANDLE  NO-UNDO.
DEFINE VARIABLE fehler   AS Progress.Lang.Error NO-UNDO.

connId = apsv.AppServer:ConnectApsv().

/* Abbruch Kriterium */
IF connId = -1 THEN DO:
    MESSAGE "Connection Failed"
    VIEW-AS ALERT-BOX.
    QUIT.
END.

/* save for later */
RUN file_transfer_apsv/receive_file.p PERSISTENT SET res.

/* execute proc on Apsv */
RUN file_transfer_apsv/create_file.p ON SERVER apsv.AppServer:GetAppServer()
                                     ASYNCHRONOUS SET req
                                     EVENT-PROCEDURE "rebuildFile" IN res
                                     ( OUTPUT TABLE transfer, OUTPUT fehler ).

/* Await response */
DO WHILE NOT req:COMPLETE:
    PROCESS events.
   
    IF req:COMPLETE THEN
        MESSAGE "req complete"
        VIEW-AS ALERT-BOX.
END.

MESSAGE "Ende"
VIEW-AS ALERT-BOX.

create_file.p
Code:
BLOCK-LEVEL ON ERROR UNDO, THROW.

DEFINE TEMP-TABLE transfer NO-UNDO
    FIELD ptr AS BLOB.

DEFINE OUTPUT PARAMETER TABLE FOR transfer.
DEFINE OUTPUT PARAMETER fehler AS Progress.Lang.Error NO-UNDO.
   
DEFINE VARIABLE pathTemplate AS CHARACTER   NO-UNDO.
DEFINE VARIABLE pathFilled   AS CHARACTER   NO-UNDO.
DEFINE VARIABLE wHaendl      AS COM-HANDLE  NO-UNDO.

pathTemplate = SUBSTITUTE( "&1template.docx", session:TEMP-DIRECTORY ).
pathFilled   = SUBSTITUTE( "&1filled.docx", session:TEMP-DIRECTORY ).



CREATE "Word.application" wHaendl.

wHaendl:Documents:Open( pathTemplate ).
wHaendl:ActiveDocument:SelectContentControlsByTitle( "test" ):item( 1 ):RANGE:TEXT = "Hallo".
wHaendl:ActiveDocument:SaveAs( pathFilled ).
   
wHaendl:QUIT(0).

CREATE transfer.
COPY-LOB FILE pathFilled TO transfer.ptr.            

CATCH onError AS Progress.Lang.Error:
    fehler = onError.
    wHaendl:QUIT(0).
END CATCH.
FINALLY:
    RELEASE OBJECT wHaendl.
END.

receive_file.p
Code:
BLOCK-LEVEL ON ERROR UNDO, THROW.
DEFINE TEMP-TABLE transfer NO-UNDO
    FIELD ptr AS BLOB.

PROCEDURE rebuildFile:
    DEFINE INPUT PARAMETER TABLE FOR transfer.
    DEFINE INPUT PARAMETER fehler AS Progress.Lang.Error NO-UNDO.
   
    DEFINE VARIABLE i     AS INTEGER NO-UNDO.
    DEFINE VARIABLE pfad  AS CHARACTER NO-UNDO.
   
    pfad = SUBSTITUTE( "&1received.docx", session:TEMP-DIRECTORY ).
   
    MESSAGE "in response"
    VIEW-AS ALERT-BOX.
   
    IF fehler <> ? THEN DO:
        DO i = 0 TO fehler:NumMessages :
           
            MESSAGE fehler:GetMessage(i)
            VIEW-AS ALERT-BOX.
           
        END.
        RETURN.
    END.
   
    FIND FIRST transfer NO-ERROR.
   
    IF AVAILABLE transfer THEN
        COPY-LOB transfer.ptr TO FILE pfad.
END PROCEDURE.
 

Stefan

Well-Known Member
It seems like you are out of luck - COM objects on PASOE raise "CoInitialize has not been called." error

PASOE multi-threaded agent doesn't initialize all threads correctly initialized to support COM objects.
As result: If a request to run an ABL program that uses COM objects gets assigned to the wrong thread, the code will fail.

COM automation is not currently supported on PASOE multi-session agents. CoInitialize/CoInitializeEx would need to be called per thread for this to work. This issue does not exist when running on the classic AppServer because the agent is single-threaded
 
Last edited:

swip

New Member
That's a bummer! Are there any alternative to create word documents without com-handle?
 

Stefan

Well-Known Member
We replaced our com-handle Excel documents a long long time ago with office xml documents. These were replace a long time ago by xslx.

An xslx is a zipped container of various xml documents which can all be generated by ABL and then zipped by a .Net class or a Linux zip.

The same applies to a docx.
 
Top