Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

GhostScript problem 3

Status
Not open for further replies.

Brezhnev

Programmer
Sep 25, 2002
53
CA
Hi!
Some time ago I did a project in VisualFox6 ..that converts .FRX file to .PDF file. Very tricky but eventually it works ( printing .FRX file to .PS file (PostScript) and then thru GhostScript converting it to .PDF)... So I resolved pretty much all problems but still left with one : if .FRX file is to big ( more then 100 pages) -- it takes a lot of time ( eventually converts it ) ... the problem that I can't see how to see how long it takes ?!?! I need to provide user with the feedback 'cause if he's trying to run next export it will create invalid .PDF. So, my question is how to calculate how long GhostScript will take to convert .PS file to .PDF ? Or maybe I should use some other converter? By the way.. I am running it (GhostScript) thru WinExec....

Thank you
 
Brezhnev

'I am running it (GhostScript) thru WinExec....'

There lies your problem - control is returning to VFP before the process launched by WinExec is complete.

You will not be able to use a progress bar to determine where you are with the printing of the report.

I suggest you play an .avi file instead which will show the user processing is taking place.

Instead of WinExec() use CreateProcess(), an example of which can be found at
This example would keep control with Ghostscript until such time as Ghostscript has completed its processing, whereupon control returns to VFP.

What you can do is disable any control(s) when the process starts and enable those control(s) when the process finishes. HTH

Chris [pc2]
 
thanx a lot ... i think this is it ...:):)
i will try it out ..
 

I use ghostscipt for my reports and have found it to be quite fast a 100 - 150 page report does not take more than 20 seconds - for the entire process - creation of the ps file and the conversion from ps to pdf. I have tested a 9999 page report and the total time taken was around 20 minutes.

 
Additionally the version which I use - which is from universalthread.com uses createprocess and not winexec.



 
hi guys! still need help (((
everything is fine ... but ... here is code i have problem with :

* Use timeout of TIMEOUT_INTERVAL msec so the display
* will be updated. Otherwise, the VFP window never
* repaints until
* the loop is exited.

DO WHILE .T.
IF WaitForSingleObject(hProcess, WAIT_INTERVAL)! = WAIT_TIMEOUT
EXIT
ELSE
DOEVENTS
ENDIF
ENDDO

( code is from Q191584)

How I know WAIT_INTERVAL and WAIT_TIMEOUT ??? Totally confused ! ((
Please help ... Before using CloseHandle ..I need to know that GhostScript finished ... How ???

Thanks alot again for help...
 
From the code I use:

m_cmd = [ -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE#pdfwrite -sOutputFile#]+m_outfile +[ -dnodisplay -dCompatibilityLevel#1.2 -c .setpdfwrite -f ] +m_ifilename
m_cmd = (gs)+ m_cmd +Chr(0)

** this is the actual command sent to ghostscript

Do runme With m_cmd

Proc runme
Para m_cmd
#Define NORMAL_PRIORITY_CLASS 32
#Define IDLE_PRIORITY_CLASS 64
#Define HIGH_PRIORITY_CLASS 128
#Define REALTIME_PRIORITY_CLASS 1600

* Return code from WaitForSingleObject() if
* it timed out.
#Define WAIT_TIMEOUT 0x00000102

* This controls how long, in milli secconds, aitForSingleObject()
* waits before it times out. Change this to suit your preferences.
#Define WAIT_INTERVAL 200

Declare Integer CreateProcess In kernel32.Dll ;
INTEGER lpApplicationName, ;
STRING lpCommandLine, ;
INTEGER lpProcessAttributes, ;
INTEGER lpThreadAttributes, ;
INTEGER bInheritHandles, ;
INTEGER dwCreationFlags, ;
INTEGER lpEnvironment, ;
INTEGER lpCurrentDirectory, ;
STRING @lpStartupInfo, ;
STRING @lpProcessInformation

Declare Integer WaitForSingleObject In kernel32.Dll ;
INTEGER hHandle, Integer dwMilliseconds

Declare Integer CloseHandle In kernel32.Dll ;
INTEGER hObject

Declare Integer GetLastError In kernel32.Dll

* STARTUPINFO is 68 bytes, of which we need to
* initially populate the 'cb' or Count of Bytes member
* with the overall length of the structure.
* The remainder should be 0-filled
Start = long2str(68) + Replicate(Chr(0), 64)

* PROCESS_INFORMATION structure is 4 longs,
* or 4*4 bytes = 16 bytes, which we'll fill with nulls.
process_info = Replicate(Chr(0), 16)
* Start a copy of gs (EXE name must be null-terminated)
File2Run = m_cmd

* Call CreateProcess, obtain a process handle. Treat the
* application to run as the 'command line' argument, accept
* all other defaults. Important to pass the start and
* process_info by reference.
lcStartupInfo = getStartupInfo()
** the older startup
* I didn't want ghostscript to show, so I changed the startup
* of create process to run without a visual element.
* to have GS start visually, change @lcStartupInfo, below to be @start
RetCode = CreateProcess(0, File2Run, 0, 0, 1, ;
NORMAL_PRIORITY_CLASS , 0, 0, @lcStartupInfo, @process_info)

* Unable to run, exit now.
If RetCode = 0
=Messagebox("Error occurred. Error code: ", GetLastError())
Return
Endif

* Extract the process handle from the
* PROCESS_INFORMATION structure.
hProcess = str2long(Substr(process_info, 1, 4))

Do While .T.
* Use timeout of TIMEOUT_INTERVAL msec so the display
* will be updated. Otherwise, the VFP window never repaints until
* the loop is exited.
If WaitForSingleObject(hProcess, WAIT_INTERVAL) != WAIT_TIMEOUT
Exit
Else
DoEvents
Endif
Enddo
* removed to enable to run without user intervention
* =MESSAGEBOX ("Process completed")
RetCode = CloseHandle(hProcess)
Return
 
Brezhnev

As you can see from the code posted by mm0000, those two constants have been defined in the MSDN example, so you need not give them a value.

#Define WAIT_TIMEOUT 0x00000102
* This controls how long, in milli secconds, WaitForSingleObject()
* waits before it times out. Change this to suit your preferences.
#Define WAIT_INTERVAL 200
FAQ184-2483 - the answer to getting answered.​

Chris [pc2]
 
hi again ... the funny part is -- i am using the exact same code ... the only thing that i would like you to explain is :
*--------
lcStartupInfo = getStartupInfo()
** the older startup
* I didn't want ghostscript to show, so I changed the startup
* of create process to run without a visual element.
* to have GS start visually, change @lcStartupInfo, below to be @start
RetCode = CreateProcess(0, File2Run, 0, 0, 1, ;
NORMAL_PRIORITY_CLASS , 0, 0, @lcStartupInfo, @process_info)

*---------
So I have Start wich is :lcStart = long2str(68) + REPLICATE(CHR(0), 64)
and I have process_info wich is : REPLICATE(CHR(0), 16)

but what is lcStartupInfo = getStartupInfo()???

I still have the same problem : if it's more then 50 pages long -- it stops converting at some point and runs forever... Any ideas ?

Thank you all ..
 
Brezhnev

This is what I use

FUNCTION GetStartupInfo

*!* creates the STARTUP structure to specify main window
*!* properties if a new window is created for a new process

*| typedef struct _STARTUPINFO {
*| DWORD cb; 4
*| LPTSTR lpReserved; 4
*| LPTSTR lpDesktop; 4
*| LPTSTR lpTitle; 4
*| DWORD dwX; 4
*| DWORD dwY; 4
*| DWORD dwXSize; 4
*| DWORD dwYSize; 4
*| DWORD dwXCountChars; 4
*| DWORD dwYCountChars; 4
*| DWORD dwFillAttribute; 4
*| DWORD dwFlags; 4
*| WORD wShowWindow; 2
*| WORD cbReserved2; 2
*| LPBYTE lpReserved2; 4
*| HANDLE hStdInput; 4
*| HANDLE hStdOutput; 4
*| HANDLE hStdError; 4
*| } STARTUPINFO, *LPSTARTUPINFO; total: 68 bytes

#DEFINE STARTF_USESHOWWINDOW 1
#DEFINE SW_SHOWNORMAL 1
#DEFINE SW_SHOWHIDDEN 0

RETURN num2dword(68) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(STARTF_USESHOWWINDOW) ;
+ num2word(SW_SHOWHIDDEN) ;
+ num2word(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0) ;
+ num2dword(0)

FUNCTION num2dword(lnValue)

#DEFINE m0 256
#DEFINE m1 65536
#DEFINE m2 16777216
LOCAL b0, b1, b2, b3
b3 = INT(lnValue/m2)
b2 = INT((lnValue - b3 * m2)/m1)
b1 = INT((lnValue - b3*m2 - b2*m1)/m0)
b0 = MOD(lnValue, m0)
RETURN CHR(b0) ;
+ CHR(b1) ;
+ CHR(b2) ;
+ CHR(b3)
****************

'if it's more then 50 pages long -- it stops converting at some point and runs forever...'

Wasn't aware you had this problem. Please provide any more detail you may have.
FAQ184-2483 - the answer to getting answered.​

Chris [pc2]
 

As I have mentioned previously I regularly run reports greater than 100 pages in length and I have no problems at all. Maybe you are using an earlier verion of Ghostscript -I use ver 7.04 = if you are using an earlier try downloading version 7.04

 
yes ..i am using GhostScript 7.04 ... Currently running tests ...as long as file that i am converting is less then 1000k -- it's fine ...but if it's more -- GhostScript keeps running , .PDF file gets created but some small part of it ( like 50 to 100 k and if you trying to open it -- file is corrupted) ... and GhostScript looks like still trying to do it's job ( .PS file is in use all this time) ... Any kind of limitation on the size of the file ??? But mm0000 , you're saying -- no problem , right ???
Still testing ...
 
ok ... so my test are showing that size does't matter ...
i have problems with particular reports only ... mm0000 absolutely right , i just exported 420 pages ..in 4 minutes! no problem .... But it hangs or gives an error with couple of reports and I don't see what is so special about them ... Any ideas ?
 
Brezhnev

One thing you try is to print your report to the .ps file and not run Ghostscript.

Then run Ghostscript from the command line. If successful, it's indicating that Ghostscript is possibly trying to process an incomplete .ps file.

If that is the case, then you may have to force VFP to wait until the .ps file is complete, before you run Ghostscript.

To effect that you can use the return value from FOPEN() running in a loop containing a pause of n second(s) to determine if the file is complete.

What Postcript driver are you using?
What Version of Windows are you using?
FAQ184-2483 - the answer to getting answered.​

Chris [pc2]
 
well ..that's exactly what I do :
first I print .FRX file to PS file ... setting printer to Generic PostScript ..then (just after it's finished) I take .PS file and run GhostScript with it... I even checked manually that PS file is comlete and fine...

I use HP Laser for driver ... and I am running Windows XP

So far ( no matter of the size) I have problems only with 2 reports out of 24 so far tested ... Whatever is different on those two -- bigger detail line ( 3' and 7' respectivly)... ??????? what difference does it make ?? hmm....
 
There is no problem with file sizes - the 9999 page report I generated was more 30+ MB in size. One possiblity could be the using the HP driver - try using Abodes Generic Postscipt drive (which I use) and freely downloadble from Adobes website.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top