2010-09-16 112 views
10

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 estoy recibiendo es "Nombre de la impresora no es válido" Esto es lo que estoy usando para obtener el nombre de la impresora:Impresión desde ASP.NET a una impresora de red

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?

+2

Bajo qué contexto usuario está ejecutando ASP.NET? ¿Estás usando suplantación? ¿Cuáles son los permisos en la impresora? – Heinzi

+0

Se está ejecutando en ASP.NET Development Server, por lo que supongo que se está ejecutando bajo mi cuenta de Windows. Puedo imprimir directamente desde el Bloc de notas a esa impresora de servidor. – Prabhu

Respuesta

5

hay problemas con las credenciales que se podía resolver por suplantación o derechos ascendentes del usuario de la aplicación web se ejecuta bajo.

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

Se utilizó el Printing.PrintDocument como tal (Código de 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() 
+0

Entonces, ¿puedo usar \\ miservidor \ myprinter como PrinterName? – Prabhu

+0

dejamos afuera \\ miservidor \. Otra de las palabras que llamamos en el servidor es cómo lo llamamos. Nada de rutas UNC ni nada. – klabranche

+0

Oh ok ... ¿Quiere decir que instaló la impresora de red como una impresora local? – Prabhu

5

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 contrario, los servicios de Windows por lo general se ejecutan bajo cuenta del sistema local (con altos privilegios)

+0

Gracias ... ¿Sabría cómo puedo configurarlo para darle los privilegios suficientes? – Prabhu

+0

Hola, soy un programador, no un SysOp. Pregunte [por allí] (http://serverfault.com/) –

+0

Gracias. Comprobé que tampoco funciona desde una aplicación de Windows Forms. – Prabhu

0

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

Si la red es configurado para usuarios de dominio y de la impresora se añade a imprimir servidor:

  • NombreImpresora que se define como = "\\ PrintServerIP_OR_Name \\ NombreImpresora" Ejemplo: PrinterSettings.PrinterName = "\\ 15.1.1.1 \\ prn001"
  • Comprobar el conjunto de permisos en el acceso a la impresora
  • que, o bien ser usuarios del dominio o Todo el mundo
  • Si los usuarios del dominio, a continuación, el código C# pueden encerrarse dentro de la suplantación que se puede utilizar para llamar al código de impresión, que es la siguiente:
/// <summary> 
    /// Does the actual impersonation. 
    /// </summary> 
    /// <param name="userName">The name of the user to act as.</param> 
    /// <param name="domainName">The domain name of the user to act as.</param> 
    /// <param name="password">The password of the user to act as.</param> 
    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); 
      } 
     } 
    } 

    /// <summary> 
    /// Reverts the impersonation. 
    /// </summary> 
    private void UndoImpersonation() 
    { 
     if (impersonationContext!=null) 
     { 
      impersonationContext.Undo(); 
     } 
    } 

    private WindowsImpersonationContext impersonationContext = null; 

en primer lugar hacer una llamada a suplantar al usuario y luego llamar a la función de impresión que se vería como a continuación:

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

Cuestiones relacionadas