prowin32.exe and crystal (poor performance)

Wro

New Member
When I print a lot of reports in crystal, prowin32.exe the use of memory is increased excessively. I can understand this. The problem comes when I finish printing that prowin32.exe does not release this ram. The problem gets worst in Terminal Server where users print simultaneously. If I minimize the application the ram it releases but it follows in virtual memory great part of this. In the end the only solution that is is to close prowin32 :(
How can I release ram memory of prowin32.exe once the print is finished?

thanks.

Robert
 
How are you printing the reports? Which Progress and Crystal versions? Does your code clean up any handles it creates?
 
Hello and thank you for your attention.

I just read the reports by this command:

CREATE "CrystalRuntime.Application":U hCRApp NO-ERROR.
hCRRpt = hCRApp:OpenReport("c:\myreport.rpt", 1).

BUT, i read about 800 reports in one time ("c:\myreport.rpt" is replaced by a variable). My program reads a directory and all sub-directories, and for all report found I read it to find the tables used in.

When I read about 400 reports, I have no error, but the prowin32.exe grows up a lot. After about 400 report I have the following message (I think because of the BIG memory taken by the prowin32.exe):

error.jpg
Enregistrement TLV non valide. (Invalid TLV Record)


I Release hCRApp and hCRRpt at each read but it doesn't change anything.

My Progress version is 9.1E

My Crystal version is:
For developpement: Crystal 2008
For viewer progress: crviewer.dll - version:11.5.0.313


PS: excuse my bad english, I am french.
 
If I would have to speculate I would say that the problem is that you would need to release the COM-HANDLE from time to time. If I were you, I would implement a logic that would release the COM-HANDLE after each - say - 100 reports, create a new one and than continue processing the pending reports.

Heavy Regards, RealHeavyDude.
 
Thank you for your answer RealHeavyDude but I already release the COM-HANDLE after EACH report.
Excuse my bad english but I don't understand when you say "create a new one and than continue processing the pending reports".

Is there any solution to release the prowin32.exe?
 
Sorry for being unclear. But the only way to release the prowin32.exe is to end the run time session ...
I meant to create a new COM-HANDLE.

By the way, your English is sufficient - it is not my native language too ...

How and when do you release the COM-HANDLE?

Heavy Regards, RealHeavyDude.
 
here is my code called by a repeat procedure:

Code:
    /* *** Definitions *** */
    /* Tables tempo */
    DEF TEMP-TABLE wtables
          FIELD nomtable AS CHAR.
    
    DEF TEMP-TABLE wetatscr
          FIELD etatcr      AS CHAR
          FIELD nomtable    AS CHAR
          FIELD nomalias    AS CHAR
          FIELD emplacement AS CHAR.

/* *** Procedure *** */
PROCEDURE CrystalReport:

    DEF INPUT PARAM i-cr AS CHAR NO-UNDO. /* Crystal Report file */
    DEF VAR hCRRpt            AS COM-HANDLE NO-UNDO.
    DEF VAR hCRApp            AS COM-HANDLE NO-UNDO.
    DEF VAR ch-CRsection      AS COM-HANDLE NO-UNDO.
    DEF VAR ch-CRReportObject AS COM-HANDLE NO-UNDO.
    DEF VAR ch-CRSubReport    AS COM-HANDLE NO-UNDO.
    DEF VAR nItem     AS INT  NO-UNDO.
    DEF VAR nsec      AS INT  NO-UNDO.
    DEF VAR nBase     AS INT  NO-UNDO.
    DEF VAR wtabletmp AS CHAR NO-UNDO.

    /* Ouverture de l'état */
    CREATE "CrystalRuntime.Application":U hCRApp NO-ERROR.
    hCRRpt = hCRApp:OpenReport(i-cr, 1).

    /* Recherche des tables */
    DO nBase = 1 TO hCRRpt:DATABASE:tables:COUNT:   /* ETAT PRINCIPAL */
        ASSIGN wtabletmp = hCRRpt:Database:Tables(nBase):location NO-ERROR.
        FIND FIRST wtables WHERE wtables.nomtable = wtabletmp NO-LOCK NO-ERROR.
        IF AVAIL wtables THEN DO:
           CREATE wetatscr.
           ASSIGN wetatscr.etatcr   = i-cr
           wetatscr.nomtable = wtabletmp
           wetatscr.nomalias = hCRRpt:Database:Tables(nBase):NAME
           wetatscr.emplacement = "Etat principal".
        END.
    END.
    DO nSec = 1 TO hCRRpt:Sections:COUNT:   /* Ss-ETAT */
        ch-CRsection = hCRRpt:Sections:ITEM(nSec).
        DO nItem = 1 TO ch-CRsection:reportObjects:COUNT:
            ch-CRReportObject = ch-CRsection:ReportObjects:ITEM(nItem).
            IF ch-CRReportObject:kind = 5 THEN DO : /* Ne prendre que les sous etats */
                ch-CRSubReport = ch-CRReportObject:OpenSubreport.
                DO nBase = 1 TO ch-CRSubReport:DATABASE:tables:COUNT:
                    ASSIGN wtabletmp = hCRRpt:Database:Tables(nBase):location NO-ERROR.
                    FIND FIRST wtables WHERE wtables.nomtable = wtabletmp NO-LOCK NO-ERROR.
                    IF AVAIL wtables THEN DO:
                        CREATE wetatscr.
                        ASSIGN wetatscr.etatcr   = i-cr
                                    wetatscr.nomtable = wtabletmp
                                    wetatscr.nomalias = hCRRpt:Database:Tables(nBase):NAME
                                    wetatscr.emplacement = "Sous-état".
                    END.
                END.
            END.
        END.
    END.

    /* Libère les objets */
    RELEASE OBJECT hCRRpt.
    RELEASE OBJECT hCRApp.

END.
 
Frankly, I can't see any flaw in your code. Nevertheless I would check whether a re-use of the COM-HANDLE to the "CrystalRuntime.Application" is opportune as you say you call it some 400 times and then errors start to pop up. Other than that I have no real suggestion apart from the knowledge base where you can find a slew of articles when searching for 5890 ...

Furthermore Progress 9.1e is very, very, very old software - if there is any chance you should upgrade to a more recent version of OpenEdge.

Heavy Regards, RealHeavyDude.
 
Please add code tags around your code! You are making it unneccessarily hard to read.

You have five com-handles but are only releasing two - is that correct? Shouldn't you be releasing ch-CRsection when done? The same applies to the others (see !!! in code below).

Code:
/* *** Definitions *** */
/* Tables tempo */
DEF TEMP-TABLE wtables
   FIELD nomtable AS CHAR.


DEF TEMP-TABLE wetatscr
   FIELD etatcr AS CHAR
   FIELD nomtable AS CHAR
   FIELD nomalias AS CHAR
   FIELD emplacement AS CHAR.


/* *** Procedure *** */
PROCEDURE CrystalReport:


   DEF INPUT PARAM i-cr AS CHAR NO-UNDO. /* Crystal Report file */


   DEF VAR hCRRpt AS COM-HANDLE NO-UNDO.
   DEF VAR hCRApp AS COM-HANDLE NO-UNDO.
   DEF VAR ch-CRsection AS COM-HANDLE NO-UNDO.
   DEF VAR ch-CRReportObject AS COM-HANDLE NO-UNDO.
   DEF VAR ch-CRSubReport AS COM-HANDLE NO-UNDO.

   DEF VAR nItem AS INT NO-UNDO.
   DEF VAR nsec AS INT NO-UNDO.
   DEF VAR nBase AS INT NO-UNDO.
   DEF VAR wtabletmp AS CHAR NO-UNDO.

   /* Ouverture de l'état */
   CREATE "CrystalRuntime.Application":U hCRApp NO-ERROR.
   hCRRpt = hCRApp:OpenReport(i-cr, 1).

   /* Recherche des tables */
   DO nBase = 1 TO hCRRpt:DATABASE:tables:COUNT: /* ETAT PRINCIPAL */
      ASSIGN wtabletmp = hCRRpt:DATABASE:Tables(nBase):location NO-ERROR.
      FIND FIRST wtables WHERE wtables.nomtable = wtabletmp NO-LOCK NO-ERROR.
      IF AVAIL wtables THEN DO:
         CREATE wetatscr.
         ASSIGN wetatscr.etatcr = i-cr
            wetatscr.nomtable = wtabletmp
            wetatscr.nomalias = hCRRpt:DATABASE:Tables(nBase):NAME
            wetatscr.emplacement = "Etat principal".
      END.
   END.
   DO nSec = 1 TO hCRRpt:Sections:COUNT: /* Ss-ETAT */
      ch-CRsection = hCRRpt:Sections:ITEM(nSec).
      DO nItem = 1 TO ch-CRsection:reportObjects:COUNT:
         ch-CRReportObject = ch-CRsection:ReportObjects:ITEM(nItem).
         IF ch-CRReportObject:kind = 5 THEN DO : /* Ne prendre que les sous etats */
            ch-CRSubReport = ch-CRReportObject:OpenSubreport.
            DO nBase = 1 TO ch-CRSubReport:DATABASE:tables:COUNT:
               ASSIGN wtabletmp = hCRRpt:DATABASE:Tables(nBase):location NO-ERROR.
               FIND FIRST wtables WHERE wtables.nomtable = wtabletmp NO-LOCK NO-ERROR.
               IF AVAIL wtables THEN DO:
                  CREATE wetatscr.
                  ASSIGN wetatscr.etatcr = i-cr
                     wetatscr.nomtable = wtabletmp
                     wetatscr.nomalias = hCRRpt:DATABASE:Tables(nBase):NAME
                     wetatscr.emplacement = "Sous-état".
               END.
            END.
            RELEASE ch-CRSubReport. /* !!! */
         END.
         RELEASE ch-CRReportObject. /* !!! */
      END.
      RELEASE ch-CRsection. /* !!! */
   END.


   /* Libère les objets */
   RELEASE OBJECT hCRRpt.
   RELEASE OBJECT hCRApp.


END PROCEDURE.
 
Thank you RealHeavyDude and Stefan.

I arrive to have correct "growing up" memory of the prowin32.exe thanks to you.

I have done two things:

1: I use the COM-HANDLE "CrystalRuntime.Application" only ONE time at the beginning (thank you RealHeavyDude)
2: I have add the tree other releases (thank you Stefan - big impact on the memory)

I think i will not have performance anymore.

Thank you to all
 
Back
Top