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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Print with ShellExecute, CreateProcess and WaitForSingleObject APIs

Status
Not open for further replies.

JabbaTheNut

Programmer
Jul 29, 2002
176
US
I have used ShellExecute successfully for printing "one-off" .PDF files. However, I now have a situation in which I need to print several .PDFs in a specific order. When I use ShellExecute, the .PDFs print when ready and not necessarily in the order I specify (ShellExecute is asynchronous). I know that the CreateProcess API coupled with the WaitForSingleObject API will do the trick for me. My problem, however, is with the command line input required by the CreateProcess API. I don't know the proper syntax for printing a .PDF document from the command line. Does anyone know the proper syntax (i.e. PRINT C:\MYFile.PDF)? Game Over, Man!
 
That did not seem to work. Thanks anyway.

Any other suggestions? Game Over, Man!
 

There is an SDK you can download from adobe and it has some vb code in the samples section. Have you given that a try?

Good Luck

 
My current problem relates to printing .PDFs. However, I would like to implement the solution for other types of files as well. With that in mind, I believe the adobe SDK would only be a partial solution.

I find it very suprising that there is no commonly known solution for printing files/documents in a synchronous fashion. It would seem to me that this type of functionality would be widely used (it is a big world). Does anyone know how to print files using the CreateProcess API? Game Over, Man!
 

Not with the createprocess API but with the ShellExecuteEx API. The process that several programs that we use is as follows.

1. ShellExecuteEx with Print verb
2. Wait on spooler to start (job count > 0)
3. Wait on spooler to end (job count = 0)
4. Repeat

Now you do not need to have all of that information that we gather but you can do the same thing just a bit differently.

1. ShellExecuteEx with print verb
2. WaitForSingleObject API
3. Repeat

In the SHELLEXECUTEINFO there is the hProcess that is returned that you can use for the WaitForSingleObject
[tt]
Do While WaitForSingleObject(SEI.hProcess, 10) = WAIT_TIMEOUT
DoEvents
Loop
[/tt]

just one note though, You may want to wait on the printer to end its current job because you can degrade a system by constantly printing to the printer and not allowing it to clear. Which can happen with large documents. The called application may be done spooling and kill itself but the spooler is much slower so you can build up jobs in the spooler thus taking up disk space and system resources.

Good Luck

 
I am currently using an implementation of the ShellExecuteEx API that prints all the .PDFs I send to it. However, it does not seem to wait until the process of the first print job closes before it prints the next print job (i.e. does not print in order). Below is the code I am currently using. Please provide guidance on how I can adjust the code properly. Thanks :)

CODE...

*****DECLARATIONS SECTION*****

Private Type SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hwnd As Long
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As Long
lpIDList As Long
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type

Public Const SEE_MASK_NOCLOSEPROCESS = &H40
Public Const SW_SHOWNORMAL = 1
Public Const INFINITE = &HFFFF
Public Const WAIT_TIMEOUT = &H102

Public Declare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" (lpExecInfo As _
SHELLEXECUTEINFO) As Long

Public Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal _
dwMilliseconds As Long) As Long

*****FUNCTION SECTION*****

Public Function Shell_X(formhwnd As String, filename As String, action As String, showstyle) As Integer

Dim sx As SHELLEXECUTEINFO
Dim proc As PROCESS_INFORMATION
Dim retval As Long

' Load the information needed for action
' into the structure.
With sx
' Size of the structure
.cbSize = Len(sx)
' Use the hProcess element of the structure.
.fMask = SEE_MASK_NOCLOSEPROCESS
' Handle to the window calling this function.
.hwnd = formhwnd
' The action to perform: print the file.
.lpVerb = action 'I WILL USE 'PRINT' HERE
' The file to open.
.lpFile = filename
' No additional parameters are needed here.
.lpParameters = ""
' Simply display the window.
.nShow = showstyle
End With

' Open the file using its associated program.
retval = ShellExecuteEx(sx)

If retval <> 0 Then
' Wait for the opened process to close
' before continuing. Instead
' of waiting once for a time of INFINITE,
' this example repeatedly checks to see if the
' process is still open.
' This allows the DoEvents VB function to be
' called, preventing
' the program from appearing to lock up
' while it waits.

Do While retval = WAIT_TIMEOUT
DoEvents
retval = WaitForSingleObject(sx.hProcess, 0)
Loop

End If

End Function

*****END OF CODE*****

To call this function, I would simply do something like this...

For i = 1 to 5

Rtn = Shell_X(Me.hWnd, &quot;c:\myfile&quot; & i & &quot;.pdf&quot;, &quot;print&quot;, SW_HIDE)

Next i
Game Over, Man!
 

First off in your function declaration your first arguement

formhwnd As String

should be a long

Second your last arguement showstyle is a varient and should be an integer

Third, your retval = WaitForSingleObject(sx.hProcess, 0) has a zero arguement, I would change that to something like 10 (.01 of a second) so your program does not go through this loop as fast as it can eating up more resources.

Now, the reason that the print jobs &quot;it does not seem to wait until the process of the first print job closes before it prints the next print job (i.e. does not print in order).&quot; do not print in order may be more the fault of your spooler than your program (reread my prior post). For the printer that you are using check to see if somewhere in its settings there is the option to &quot;Print Spooled Documents First&quot; and to see if has a FIFO feature (First In First Out).

Good Luck

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top