Impresión desde ASP.NET a una impresora de red

Necesito enviar documentos a una impresora de red (\ myserver \ myprinter). Estoy usando las clases System.Printing para imprimir, y funciona bien cuando se trata de un servicio de Windows, pero desde una aplicación ASP.NET, solo puede imprimir en impresoras locales, no en impresoras de red. El error que recibo es “El nombre de la impresora no es válido” Esto es lo que estoy usando para obtener el nombre de la impresora:

public string PrinterName { using (LocalPrintServer server = new LocalPrintServer()) return server.GetPrintQueue(@"\\myserver\myprinter"); } 

¿Cuáles son mis opciones aquí? ¿Es este un problema de permisos?

Existen problemas con las credenciales que puede resolver mediante suplantación o boost los derechos del usuario con el que se ejecuta la aplicación web.

Sin embargo, lo logramos agregando la impresora de red como impresora en el servidor (agregue diálogo de impresora en el servidor) y enviando el trabajo a esa impresora.

Usamos el Printing.PrintDocument como tal (Código en VB) …

 Public Class SpecialReportPrintJob Inherits Printing.PrintDocument Protected Overrides Sub OnBeginPrint(ByVal ev as Printing.PrintEventArgs) MyBase.OnBeginPrint(ev) Me.PrinterSettings.PrinterName = "PrinterNameUsedOnServer" 'setup rest of stuff.... End Sub End Class 'And we then call it like so Dim printSpecialReport as new SpecialReportPrintJob() printSpecialReport.Print() 

De forma predeterminada, una aplicación ASP.NET se ejecuta en una cuenta especial con derechos limitados. Solo lo suficiente para servir páginas web, nada más. Entonces, tendrá que configurar el usuario de ASPNET.

Por el contrario, los servicios de Windows generalmente se ejecutan en la cuenta del sistema local (con altos privilegios)

La impresión de red desde ASP.Net/C# se puede hacer usando:

Si la red está configurada para usuarios de dominio y la impresora se agrega al servidor de impresión:

  • PrinterName se definirá como = “\\ PrintServerIP_OR_Name \\ PRINTERNAME” Ejemplo: PrinterSettings.PrinterName = “\\ 15.1.1.1 \\ prn001”
  • Compruebe el conjunto de permisos en el acceso a la impresora
  • Que sean Usuarios de dominio o Todos
  • Si los usuarios del dominio, el código C # se puede incluir en la suplantación que se puede utilizar para llamar al código de impresión, que es el siguiente:
 ///  /// Does the actual impersonation. ///  /// The name of the user to act as. /// The domain name of the user to act as. /// The password of the user to act as. private void ImpersonateValidUser( string userName, string domain, string password ) { WindowsIdentity tempWindowsIdentity = null; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; try { if ( RevertToSelf() ) { if ( LogonUser( userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token ) != 0 ) { if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 ) { tempWindowsIdentity = new WindowsIdentity( tokenDuplicate ); impersonationContext = tempWindowsIdentity.Impersonate(); } else { throw new Win32Exception( Marshal.GetLastWin32Error() ); } } else { throw new Win32Exception( Marshal.GetLastWin32Error() ); } } else { throw new Win32Exception( Marshal.GetLastWin32Error() ); } } finally { if ( token!= IntPtr.Zero ) { CloseHandle( token ); } if ( tokenDuplicate!=IntPtr.Zero ) { CloseHandle( tokenDuplicate ); } } } ///  /// Reverts the impersonation. ///  private void UndoImpersonation() { if ( impersonationContext!=null ) { impersonationContext.Undo(); } } private WindowsImpersonationContext impersonationContext = null; 

Primero haga una llamada para hacerse pasar por el usuario y luego llame a la función de impresión que se vería a continuación:

 if(ImpersonateValidUser("username", "domain", "password")) { PrintDetails(); UndoImpersonation(); }