2011-12-01 56 views
7

que estoy tratando de hacer un método en C# que desemboca todos los elementos de una cola de impresión. A continuación se muestra el código:Acceso denegado intentando purgar PrintQueue en C#

LocalPrintServer localPrintServer = new LocalPrintServer(PrintSystemDesiredAccess.AdministratePrinter); 
PrintQueue printQueue = localPrintServer.GetPrintQueue(printerName); 

if (printQueue.NumberOfJobs > 0) 
{ 
    printQueue.Purge(); 
} 

Cuando se ejecuta este código, en el constructor localPrintServer, la aplicación lanza este error: "producido una excepción al crear el objeto servidor de impresión de error Win32: Acceso denegado."

Ese constructor tiene unos sobrecargas (incluyendo el envío de ningún parámetro). Probando cualquiera de esos, supero esa línea, pero cuando llego a la llamada printQueue.Purge(), obtengo el mismo mensaje de acceso denegado que se menciona arriba.

Buscando sugerencias de cómo/qué puedo hacer para evitar esto. Puedo eliminar manualmente los trabajos de impresión de mi computadora. No estoy seguro si la aplicación se ejecuta con el mismo acceso que tengo ni cómo verificarlo.

+0

¿Ha intentado ejecutar su proceso/visual studio como administrador? – faester

+0

Configuré EXE para que Visual Studio se ejecute siempre como administrador, reinicié Visual Studio 2010 y lo intenté de nuevo. Aún obteniendo los mismos errores de acceso denegado. – Kris

+0

Intente hacer clic derecho en el archivo .exe ouptput (YourProgramName.exe) y seleccione ejecutar como administrador. – mellamokb

Respuesta

0

// utilizar esto como un ejemplo para empezar ...

/// <summary> 
/// Cancel the print job. This functions accepts the job number. 
/// An exception will be thrown if access denied. 
/// </summary> 
/// <param name="printJobID">int: Job number to cancel printing for.</param> 
/// <returns>bool: true if cancel successfull, else false.</returns> 
public bool CancelPrintJob(int printJobID) 
{ 
     // Variable declarations. 
     bool isActionPerformed = false; 
     string searchQuery; 
     String jobName; 
     char[] splitArr; 
     int prntJobID; 
     ManagementObjectSearcher searchPrintJobs; 
     ManagementObjectCollection prntJobCollection; 
     try 
     { 
      // Query to get all the queued printer jobs. 
      searchQuery = "SELECT * FROM Win32_PrintJob"; 
      // Create an object using the above query. 
      searchPrintJobs = new ManagementObjectSearcher(searchQuery); 
      // Fire the query to get the collection of the printer jobs. 
      prntJobCollection = searchPrintJobs.Get(); 

      // Look for the job you want to delete/cancel. 
      foreach (ManagementObject prntJob in prntJobCollection) 
      { 
       jobName = prntJob.Properties["Name"].Value.ToString(); 
       // Job name would be of the format [Printer name], [Job ID] 
       splitArr = new char[1]; 
       splitArr[0] = Convert.ToChar(","); 
       // Get the job ID. 
       prntJobID = Convert.ToInt32(jobName.Split(splitArr)[1]); 
       // If the Job Id equals the input job Id, then cancel the job. 
       if (prntJobID == printJobID) 
       { 
         // Performs a action similar to the cancel 
         // operation of windows print console 
         prntJob.Delete(); 
         isActionPerformed = true; 
         break; 
        } 
      } 
      return isActionPerformed; 
     } 
     catch (Exception sysException) 
     { 
      // Log the exception. 
      return false; 
     } 
} 
0

Si no te importa la limpieza de todas las colas en la máquina local, puede utilizar el siguiente fragmento. Se requiere privilegios de administrador, pero no va a lanzar excepciones:

System.ServiceProcess.ServiceController controller = new System.ServiceProcess.ServiceController("Spooler"); 
       controller.Stop(); 
       System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(@"C:\Windows\System32\spool\PRINTERS"); 

       var files = info.GetFiles(); 

       foreach (var file in files) 
       { 
        file.Delete(); 
       } 
       controller.Start(); 
11

Este problema se debe al método de GetPrintQueue estar un poco mal, ya que no permite que pase en el nivel de acceso deseado. Con su código como está, se está conectando al servidor de impresión con AdministratePrinter derechos (lo cual no tiene sentido), y se conecta a la cola de impresión con derechos de usuario predeterminados. Por lo tanto, la operación fallará, incluso si Everyone tiene derechos de administrador en la cola de impresión.

Para solucionar este problema, utilice el constructor de PrintQueue en lugar de especificar el nivel de acceso correcto:

using (PrintServer ps = new PrintServer()) { 
    using (PrintQueue pq = new PrintQueue(ps, printerName, 
      PrintSystemDesiredAccess.AdministratePrinter)) { 
     pq.Purge(); 
    } 
} 

Esto todavía puede causar errores de permiso si no se está ejecutando en el contexto de un miembro del grupo de administradores (o no se ejecuta con permisos elevados), por lo que rodear esto con un bloque try/catch es una buena idea para el código de producción.

+0

esto muy útil. También estaba tratando de hacer cambios usando el método GetPrintQueue(). +1 – HiTech

1

¿Está ejecutando su sitio web como 4.0? Me encontré con problemas cuando actualizamos nuestro sitio web de 3.5 a 4.0 Framework. La funcionalidad de purga de impresión dejó de funcionar en el Marco 4.0. Finalmente, terminé creando un servicio web que utilizaba el marco 3.5 y le pedí al sitio web 4.0 que comunicara la impresora que deseaba purgar al servicio web 3.5.

(Lo siento revivir este hilo, este fue uno de los hilos yo tropezado cuando yo estaba buscando una respuesta. Pensé en publicar esto si ayuda a alguien que se ejecuta en la misma situación)

0

Recientemente , Me encontré con el mismo problema después de actualizar el .NET Framework de 4.0 a 4.6.1. Por extraño que parezca, mi aplicación .net se estaba ejecutando en .net 3.5, pero de alguna manera se vio afectada por este cambio.

De todos modos, el camino me encontré con mi solicitud era a través de programador de tareas, y la solución es hacer clic derecho en la tarea, en general, marque la casilla denominada "Ejecutar con los privilegios más altos".

Creo que si se ejecuta en la consola, es necesario "Ejecutar como administrador" cuando se abre la ventana de cmd.