We have a .NET Web Service on Windows Server 2012 R2 to Print a Crystal Report which I have upgraded to Crystal 13. It works when I am signed on as the Application Pool Identity but fails as any other user. The Message is:
System.Drawing.Printing.InvalidPrinterException: No printers are installed.
at System.Drawing.Printing.PrinterSettings.GetHdevmodeInternal(String printer)
at System.Drawing.Printing.PrinterSettings.GetHdevmode(PageSettings pageSettings)
at CrystalDecisions.CrystalReports.Engine.PrintOptions.CopyTo(PrinterSettings printer, PageSettings page)
at CrystalDecisions.CrystalReports.Engine.FormatEngine.PrintToPrinter(Int32 nCopies, Boolean collated, Int32 startPageN, Int32 endPageN)
at CrystalDecisions.CrystalReports.Engine.ReportDocument.PrintToPrinter(Int32 nCopies, Boolean collated, Int32 startPageN, Int32 endPageN)
at FlexAbilityLabelService.Labeler.ItemLabelPrint(String rptPath, String rptSelection, String rptPrinter, Int32 rptCopies) in C:\Projects\FlexAbility\FlexAbility Labeler\FlexAbilityLabelService\Labeler.asmx.vb:line 148
Even as the Application Pool Identity, I get File Not Found when the server is in the Domain.
I know these are security issues, but the application should work! I have disabled all GPO and set appropriate permissions for the account and application pool.
Here is the code:
<WebMethod()> _
Public Function Print( _
ByVal rptPath As String, _
ByVal rptSelection As String, _
ByVal rptPrinter As String, _
ByVal rptCopies As Integer _
) As Integer
Dim strLogMsg As String = String.Empty
Try
'Create Event Log
If Not EventLog.SourceExists("FlexAbility Label Service") Then
EventLog.CreateEventSource("FlexAbility Label Service", "Application")
End If
Dim log As System.Diagnostics.EventLog = New System.Diagnostics.EventLog
log.Source = "FlexAbility Label Service"
'Read AppSettings
Dim AppSettings As System.Configuration.AppSettingsReader = New System.Configuration.AppSettingsReader
Dim strLogging As String = CType(AppSettings.GetValue("Application.Logging", GetType(System.String)), String)
Dim strServer As String = CType(AppSettings.GetValue("sqlConnection.Server", GetType(System.String)), String)
Dim strDatabase As String = CType(AppSettings.GetValue("sqlConnection.Database", GetType(System.String)), String)
Dim strUserID As String = CType(AppSettings.GetValue("sqlConnection.UserID", GetType(System.String)), String)
Dim strPassword As String = CType(AppSettings.GetValue("sqlConnection.Password", GetType(System.String)), String)
If strLogging = "True" Then
strLogMsg = "Logging Is ON" & vbCrLf _
& "Path: " & rptPath & vbCrLf _
& "Selection: " & rptSelection & vbCrLf _
& "Printer: " & rptPrinter & vbCrLf _
& "Copies: " & rptCopies & vbCrLf & vbCrLf _
& "AppSettings Read:" & vbCrLf _
& "Server: " & strServer & vbCrLf _
& "Database: " & strDatabase & vbCrLf _
& "UserID: " & strUserID & vbCrLf & vbCrLf _
& "Executing As " & WindowsIdentity.GetCurrent().Name
log.WriteEntry(strLogMsg, System.Diagnostics.EventLogEntryType.Warning)
End If
'Load Report
Dim rptDoc As ReportDocument = New ReportDocument
rptDoc.Load(rptPath, OpenReportMethod.OpenReportByDefault)
If strLogging = "True" Then log.WriteEntry("Document Loaded:" & rptPath)
'Set Database Connection
'Method 1 (Older, and Only Works with ADO! ODBC Requires ServerName = ODBC Driver)
Dim rptConnectionInfo As ConnectionInfo = New ConnectionInfo
rptConnectionInfo.ServerName = strServer
'Only Set DatabaseName for ADO Connections ?
'If rptConnectionInfo.DatabaseName > "" Then
rptConnectionInfo.DatabaseName = strDatabase
'Integrated Security does not seem to work with database change!
'rptConnectionInfo.IntegratedSecurity = True
rptConnectionInfo.IntegratedSecurity = False
rptConnectionInfo.UserID = strUserID
rptConnectionInfo.Password = strPassword
'End If
Dim rptTables As Tables = rptDoc.Database.Tables
Dim rptTable As Table
For Each rptTable In rptTables
Dim rptTableLogonInfo As TableLogOnInfo = rptTable.LogOnInfo
rptTableLogonInfo.ConnectionInfo = rptConnectionInfo
rptTable.ApplyLogOnInfo(rptTableLogonInfo)
Next
If strLogging = "True" Then _
log.WriteEntry("Database Connection Set" & vbCr _
& "Server: " & strServer & vbCr _
& "Database: " & strDatabase & vbCr _
& "UserID: " & strUserID _
)
'Set Selection
rptDoc.RecordSelectionFormula = rptSelection
If strLogging = "True" Then log.WriteEntry("Selection Formula Set: " & rptSelection)
'Set Print Options
Dim rptOptions As PrintOptions
rptOptions = rptDoc.PrintOptions
rptDoc.PrintOptions.PrinterName = rptPrinter
rptDoc.PrintOptions.PaperSource = CrystalDecisions.Shared.PaperSource.Auto
If strLogging = "True" Then _
log.WriteEntry("Print Options Set" & vbCr _
& "Printer: " & rptPrinter)
'Print Report
Try
rptDoc.PrintToPrinter(rptCopies, False, 1, 1)
If strLogging = "True" Then log.WriteEntry("Successfully Printed " & rptPath, System.Diagnostics.EventLogEntryType.SuccessAudit)
Return 0
Catch ce As CrystalDecisions.CrystalReports.Engine.EngineException
Dim logPrint As System.Diagnostics.EventLog = New System.Diagnostics.EventLog
log.Source = "FlexAbility Label Service"
log.WriteEntry("PrintToPrineter Failed!" & vbCr & _
ce.Message, System.Diagnostics.EventLogEntryType.Error)
Return -1
End Try
Catch e As Exception
Dim log As System.Diagnostics.EventLog = New System.Diagnostics.EventLog
log.Source = "FlexAbility Label Service"
strLogMsg = "Outer Exception: " & vbCrLf & e.ToString
While (e.InnerException IsNot Nothing)
strLogMsg += vbCrLf & vbCrLf & "Inner Exception: " & vbCrLf & e.InnerException.ToString
End While
log.WriteEntry(e.Message, System.Diagnostics.EventLogEntryType.Error)
log.WriteEntry(strLogMsg, System.Diagnostics.EventLogEntryType.Error)
log.WriteEntry(e.StackTrace, System.Diagnostics.EventLogEntryType.Error)
Return -1
End Try
End Function
<WebMethod()> _
Public Function PrintToFile( _
ByVal rptPath As String, _
ByVal rptSelection As String, _
ByVal rptExportPath As String
) As Integer
Dim strLogMsg As String = String.Empty
Try
'Create Event Log
If Not EventLog.SourceExists("FlexAbility Label Service") Then
EventLog.CreateEventSource("FlexAbility Label Service", "Application")
End If
Dim log As System.Diagnostics.EventLog = New System.Diagnostics.EventLog
log.Source = "FlexAbility Label Service"
'Read AppSettings
Dim AppSettings As System.Configuration.AppSettingsReader = New System.Configuration.AppSettingsReader
Dim strLogging As String = CType(AppSettings.GetValue("Application.Logging", GetType(System.String)), String)
Dim strServer As String = CType(AppSettings.GetValue("sqlConnection.Server", GetType(System.String)), String)
Dim strDatabase As String = CType(AppSettings.GetValue("sqlConnection.Database", GetType(System.String)), String)
Dim strUserID As String = CType(AppSettings.GetValue("sqlConnection.UserID", GetType(System.String)), String)
Dim strPassword As String = CType(AppSettings.GetValue("sqlConnection.Password", GetType(System.String)), String)
If strLogging = "True" Then
strLogMsg = "Logging Is ON" & vbCrLf _
& "Path: " & rptPath & vbCrLf _
& "Selection: " & rptSelection & vbCrLf _
& "Export Path: " & rptExportPath & vbCrLf & vbCrLf _
& "AppSettings Read:" & vbCrLf _
& "Server: " & strServer & vbCrLf _
& "Database: " & strDatabase & vbCrLf _
& "UserID: " & strUserID & vbCrLf & vbCrLf _
& "Executing As " & WindowsIdentity.GetCurrent().Name
log.WriteEntry(strLogMsg, System.Diagnostics.EventLogEntryType.Warning)
End If
'Load Report
Dim rptDoc As ReportDocument = New ReportDocument
rptDoc.Load(rptPath, OpenReportMethod.OpenReportByDefault)
If strLogging = "True" Then log.WriteEntry("Document Loaded:" & rptPath)
'Set Database Connection
'Method 1 (Older, and Only Works with ADO! ODBC Requires ServerName = ODBC Driver)
Dim rptConnectionInfo As ConnectionInfo = New ConnectionInfo
rptConnectionInfo.ServerName = strServer
'Only Set DatabaseName for ADO Connections
'If rptConnectionInfo.DatabaseName > "" Then
rptConnectionInfo.DatabaseName = strDatabase
'Integrated Security does not seem to work with database change!
'rptConnectionInfo.IntegratedSecurity = True
rptConnectionInfo.IntegratedSecurity = False
rptConnectionInfo.UserID = strUserID
rptConnectionInfo.Password = strPassword
'End If
Dim rptTables As Tables = rptDoc.Database.Tables
Dim rptTable As Table
For Each rptTable In rptTables
Dim rptTableLogonInfo As TableLogOnInfo = rptTable.LogOnInfo
rptTableLogonInfo.ConnectionInfo = rptConnectionInfo
rptTable.ApplyLogOnInfo(rptTableLogonInfo)
Next
If strLogging = "True" Then _
log.WriteEntry("Database Connection Set" & vbCr _
& "Server: " & strServer & vbCr _
& "Database: " & strDatabase & vbCr _
& "UserID: " & strUserID _
)
'Set Selection
rptDoc.RecordSelectionFormula = rptSelection
If strLogging = "True" Then log.WriteEntry("Selection Formula Set: " & rptSelection)
'Export Report
Try
Dim printerSettings As New PrinterSettings()
Dim pageSettings As New PageSettings()
rptDoc.PrintOptions.CopyTo(printerSettings, pageSettings)
printerSettings.PrintToFile = True
printerSettings.PrintFileName = "c:\Test.prn"
rptDoc.PrintToPrinter(printerSettings, pageSettings, False)
If strLogging = "True" Then log.WriteEntry("Successfully Printed " & rptExportPath, System.Diagnostics.EventLogEntryType.SuccessAudit)
Return 0
Catch ce As CrystalDecisions.CrystalReports.Engine.EngineException
Dim logPrint As System.Diagnostics.EventLog = New System.Diagnostics.EventLog
log.Source = "FlexAbility Label Service"
log.WriteEntry("PrintToPrineter Failed!" & vbCr & _
ce.Message, System.Diagnostics.EventLogEntryType.Error)
Return -1
End Try
Catch e As Exception
Dim log As System.Diagnostics.EventLog = New System.Diagnostics.EventLog
log.Source = "FlexAbility Label Service"
strLogMsg = "Outer Exception: " & vbCrLf & e.ToString
While (e.InnerException IsNot Nothing)
strLogMsg += vbCrLf & vbCrLf & "Inner Exception: " & vbCrLf & e.InnerException.ToString
End While
log.WriteEntry(e.Message, System.Diagnostics.EventLogEntryType.Error)
log.WriteEntry(strLogMsg, System.Diagnostics.EventLogEntryType.Error)
log.WriteEntry(e.StackTrace, System.Diagnostics.EventLogEntryType.Error)
Return -1
End Try
End Function