This is a multi-part message in MIME format.
--------------020702050705010702000306
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
You can use Ghostscript to print PDF files from the command line.
gswin32c.exe -dNOSAFER -dNOPAUSE -dBATCH -sDEVICE=mswinpr2
-sOutputFile="\\spool" "c:\myfile.pdf"
You can also do that with the Ghostscript-API (gsdll32.dll, you should
find C++ examples on the Ghostscript website).
As alternative, you can print PDFs with the Adobe Reader in two ways:
1.) Via Command Line
start acrord32.exe /p /h c:\test.pdf
Unfortunately the Adobe Reader doesn't close itself after printing.
2.) Via DDE
I attached a VB6-Module which does exactly that. Porting that to C++
shuoldn't be a problem.
Regards
Marcus
Audison.Athena@gmail.com schrieb:
> I'm a newbie to PDF related Programming. Now I want to implement a
> function : given a batch of pdf files which may be located locally or
> on some place in the network pionted to by a URL. Once scheduled a task
> and submit it, then I can wait for these to be printed. For this
> target, I surfed on the web, but can't find a library or product that
> suit my need and free from charge, and also full granted license for
> any purpose and can be use evreywhere? Can anyone give me a hint to
> implement this function and any related library which can has
> implemented related function and only little effor need to fulfill the
> ultimate task and no commercial-usage limitation. And My preferred
> language is C++ or Java. Thanks a lot.
>
--------------020702050705010702000306
Content-Type: text/plain;
name="modPrintPDF.bas"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="modPrintPDF.bas"
Attribute VB_Name = "modPrintPDF"
Option Explicit
' Get Reader PID Workstation
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long)
' Get Reader PID Terminal Server
Private Declare Function WTSEnumerateProcesses Lib "wtsapi32.dll" Alias "WTSEnumerateProcessesA" (ByVal hServer As Long, ByVal Reserved As Long, ByVal Version As Long, ByRef ppProcessInfo As Long, ByRef pCount As Long) As Long
Private Declare Sub WTSFreeMemory Lib "wtsapi32.dll" (ByVal pMemory As Long)
' Get process name
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (lpString1 As Any, lpString2 As Any) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (lpString As Any) As Long
' Get Reader path
Private Declare Function FindExecutable Lib "shell32.dll" Alias "FindExecutableA" (ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As String) As Long
' Get Reader HWND
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
' Hide Reader Window
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hWnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Const GWL_EXSTYLE = (-20)
Private Const LWA_ALPHA = &H2
Private Const WS_EX_LAYERED = &H80000
Private Const TH32CS_SNAPPROCESS As Long = 2&
Private Const MAX_PATH As Integer = 260
Private Const WTS_CURRENT_SERVER_HANDLE = 0&
Private Const SW_HIDE = 0
Private Const SWP_HIDEWINDOW As Long = &H80&
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * MAX_PATH
End Type
Private Type WTS_PROCESS_INFO
SessionID As Long
ProcessId As Long
pProcessName As Long
pUserSid As Long
End Type
Dim ReaderPID As Long
Dim ReaderhWnd As Long
Public Function PrintFile(ByVal InFile As String, Optional ByVal PrinterName As String) As Boolean
Dim Result As String
Result = GetqvPDFKeyValue("PrintingSystem")
Select Case Result
Case "1"
PrintFile = PrintFile_Reader(InFile, PrinterName)
Case Else
PrintFile = PrintFile_GS(InFile, PrinterName)
End Select
End Function
Private Function PrintFile_GS(ByVal InFile As String, Optional ByVal PrinterName As String) As Boolean
Dim ProfileString As String
Dim astrArgs() As String
If FileExists(InFile) Then
ProfileString = "-dNOSAFER -dNOPAUSE -dBATCH -dNoCancel -sDEVICE=mswinpr2"
If (PrinterName = Empty) Then
PrinterName = """\\spool"""
ProfileString = ProfileString & " -dQueryUser=3"
Else
PrinterName = "\\spool\" & PrinterName & ""
End If
astrArgs = GSProfileStringToArray(ProfileString, InFile, PrinterName)
CallGS astrArgs
PrintFile_GS = True
End If
End Function
Private Function PrintFile_Reader(ByVal InFile As String, Optional ByVal PrinterName As String) As Boolean
'On Error GoTo ErrorHandler
Dim ReaderPath As String
Dim CloseReader As Boolean
Dim lRet As Long
' Check if Adobe Reader is already running. We must determine between workstation and terminal server
' as ProcessFirst/ProcessNext also returns processes from other sessions when running a session
' in an administrators context! DDE commands can only be sent to a Reader instance in the same session.
If (IsTerminalServer = True) Then
ReaderPID = GetReaderPID_TS
Else
ReaderPID = GetReaderPID
End If
If (ReaderPID = 0) Or (ReaderDDEResponsive = False) Then
'No active DDE responsive Adobe Reader found in this session! Start one!
ReaderPath = GetReaderPath(InFile)
ReaderPID = Shell(ReaderPath, vbHide)
If (ReaderPID > 32) Then
CloseReader = True
GetReaderhWnd ' Get hwnd of Adobe Reader
Sleep 1000 ' Wait for a second to make sure Adobe Reader is responsive
End If
End If
If (ReaderPID > 0) Then
If (CloseReader = True) Then
ShowWindow ReaderhWnd, SW_HIDE ' Hide Adobe Reader
MakeTransparent ReaderhWnd, 0 ' Damn Bitch
End If
If (PrinterName = Empty) Then
' Print on Windows default printer
SendDDEMessage "acroview", "control", "[FilePrintSilent(""" & InFile & """)]"
Else
SendDDEMessage "acroview", "control", "[FilePrintTo(""" & InFile & """, """ & PrinterName & """, """", """")]"
End If
If (CloseReader = True) Then
ShowWindow ReaderhWnd, SW_HIDE ' Hide Adobe Reader
Sleep 1000 ' Wait for a second...again
SendDDEMessage "acroview", "control", "[AppExit]"
End If
PrintFile_Reader = True
Else
PrintFile_Reader = False
End If
Exit Function
ErrorHandler:
PrintFile_Reader = False
End Function
Private Function GetReaderPID() As Long
' On Local Error Resume Next
' Checks if AcroRd32.exe is running and returns the PID
Dim hSnapShot As Long
Dim Result As Long
Dim ProcessEXEName As String
Dim Process As PROCESSENTRY32
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
If hSnapShot <> 0 Then
Process.dwSize = Len(Process)
Result = ProcessFirst(hSnapShot, Process)
Do While Result <> 0
ProcessEXEName = Process.szExeFile
' Um den vollen Pfadnamen unter Windows NT basierenden Systemen
' auszulesen, siehe http://support.microsoft.com/support/kb/articles/Q187/9/13.asp.
ProcessEXEName = LCase(Left$(ProcessEXEName, InStr(ProcessEXEName, Chr$(0)) - 1))
If ProcessEXEName = "acrord32.exe" Then
GetReaderPID = Process.th32ProcessID
Exit Do
End If
Result = ProcessNext(hSnapShot, Process)
Loop
Call CloseHandle(hSnapShot)
End If
End Function
Private Function GetReaderPID_TS() As Long
' On Local Error Resume Next
' Checks if AcroRd32.exe is running and returns the PID
Dim lCount As Long
Dim I As Long
Dim qvPDF_PID As Long
Dim lpBuffer As Long
Dim lp As Long
Dim lSID As Long
Dim udtProcessInfo As WTS_PROCESS_INFO
qvPDF_PID = GetCurrentProcessId
If WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0&, 1, lpBuffer, lCount) Then
' Get the current SessionID
lp = lpBuffer
For I = 1 To lCount
CopyMemory udtProcessInfo, ByVal lp, LenB(udtProcessInfo)
If (qvPDF_PID = udtProcessInfo.ProcessId) Then
lSID = udtProcessInfo.SessionID
Exit For
End If
lp = lp + LenB(udtProcessInfo)
Next
' Get AcroRD32-PID in this Session
lp = lpBuffer
For I = 1 To lCount
CopyMemory udtProcessInfo, ByVal lp, LenB(udtProcessInfo)
If (udtProcessInfo.SessionID = lSID) And (LCase(GetStrFromPtrA(udtProcessInfo.pProcessName)) = "acrord32.exe") Then
GetReaderPID_TS = udtProcessInfo.ProcessId
Exit For
End If
lp = lp + LenB(udtProcessInfo)
Next
WTSFreeMemory lpBuffer
End If
End Function
Private Sub GetReaderhWnd()
Call EnumWindows(AddressOf EnumWindowsProc, -1)
End Sub
Private Function ReaderDDEResponsive() As Boolean
ReaderDDEResponsive = (SendDDEMessage("acroview", "control", "") = ExDdeError_Success)
End Function
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
Dim TestPID As Long
Dim WindowText As String
GetWindowThreadProcessId hWnd, TestPID
If TestPID = ReaderPID Then
ReaderhWnd = hWnd
WindowText = Space$(256)
GetWindowText hWnd, WindowText, Len(WindowText)
If (InStr(WindowText, "Reader") > 0) Then
ReaderhWnd = hWnd
EnumWindowsProc = 0
Exit Function
End If
End If
EnumWindowsProc = 1
End Function
Private Function GetStrFromPtrA(lpszA As Long) As String
On Local Error Resume Next
GetStrFromPtrA = String$(lstrlen(ByVal lpszA), 0)
Call lstrcpy(ByVal GetStrFromPtrA, ByVal lpszA)
End Function
Private Sub MakeTransparent(ByVal hWnd As Long, Percentage As Integer)
On Error Resume Next
Dim Style As Long
If ((Percentage >= 0) And (Percentage <= 255)) Then
Style = GetWindowLong(hWnd, GWL_EXSTYLE)
Style = Style Or WS_EX_LAYERED
SetWindowLong hWnd, GWL_EXSTYLE, Style
SetLayeredWindowAttributes hWnd, 0, Percentage, LWA_ALPHA
End If
End Sub
Public Function GetReaderPath(Optional ByVal PDF_FilePath As String) As String
On Local Error Resume Next
Dim Result As String
Dim ReaderPath As String
Dim TempPDFFileCreated As Boolean
Result = GetqvPDFKeyValue("ReaderPath")
If (Result = Empty) Then
If Not FileExists(PDF_FilePath) Then
PDF_FilePath = GetTempFileName & ".pdf"
WriteLogFile PDF_FilePath, Empty
TempPDFFileCreated = True
End If
ReaderPath = String(MAX_PATH, 32)
FindExecutable PDF_FilePath, vbNullString, ReaderPath
GetReaderPath = ReaderPath
If (TempPDFFileCreated = True) Then
DeleteFile PDF_FilePath
End If
Else
GetReaderPath = Result
End If
End Function
--------------020702050705010702000306--
|