Skip to Content
0
May 29, 2018 at 11:05 PM

No Printers Are Installed in Web Application

194 Views Last edit Jun 08, 2018 at 02:15 PM 2 rev

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