2010-07-19 5 views
3

Dans un réseau local normalement, les imprimantes sont partagées, et nous pouvons ajouter ces ordinateurs partagés dans le réseau local à notre machine via Windows "Ajouter une imprimante distante". Je veux obtenir la liste des imprimantes ajoutées comme ceci, et le statut en ligne et les paramètres de l'imprimante par C#. La liste des imprimantes a pu être obtenue parComment obtenir le nom d'ordinateur et l'adresse IP à laquelle une imprimante est connectée en LAN

System.Drawing.Printing.PrinterSettings.InstalledPrinters 

à travers ce code, je peux obtenir la liste des imprimantes ajoutées à une zone de liste déroulante. Le problème est comment puis-je obtenir le statut en ligne de chaque imprimante, et il existe d'autres paramètres possibles grâce au code C#. S'il vous plaît aider.

+0

Jonathan, fletcher et p.campbell vous ont donné des réponses incroyablement bonnes (en moins d'une demi-heure). Je suis sûr que vous avez seulement oublié de remettre vos efforts en question, avant que vous n'en demandiez encore plus ... Je serais moi-même en colère une fois que je verrais votre propre vote. –

Répondre

2

Comme alternative à WMI, vous pouvez utiliser la Print Spooler API pour recueillir des informations détaillées sur les imprimantes. La plupart des signatures P/Invoke pour l'API sont disponibles sur http://www.pinvoke.net.

Ouvrir une poignée sur une imprimante: http://www.pinvoke.net/default.aspx/winspool.OpenPrinter

recueillir de l'information de l'imprimante: http://www.pinvoke.net/default.aspx/winspool.GetPrinterData

Edit:

rapidement fracassé ensemble un exemple de ce que vous pouvez recueillir de l'PrintSpoolerApi selon la demande.

PrintSpoolerAPIExample:

Créer un nouveau projet de console et remplacer tout le code dans Program.cs avec ce (.NET 3.5 et au-dessus, en raison de l'inférence de type), les détails de chaque imprimante disponible sur la machine (ou locale en réseau) sera imprimé sur la console. La valeur d'état est ce qui vous intéresse. Le code d'état pour "Prêt" est 0, déconner en désactivant les imprimantes et en désactivant votre connexion réseau aux imprimantes en réseau pour voir le changement d'état.

using System; 
using System.Collections; 
using System.ComponentModel; 
using System.Runtime.InteropServices; 
using System.Text; 

namespace PrintSpoolerAPIExample 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var printers = System.Drawing.Printing.PrinterSettings.InstalledPrinters as IEnumerable; 

      foreach (string printer in printers) 
      { 
       var printerInfo = PrintSpoolerApi.GetPrinterProperty(printer); 
       StringBuilder sb = new StringBuilder(); 
       sb.AppendLine(string.Format("ServerName:{0}", printerInfo.ServerName)); 
       sb.AppendLine(string.Format("PrinterName:{0}", printerInfo.PrinterName)); 
       sb.AppendLine(string.Format("ShareName:{0}", printerInfo.ShareName)); 
       sb.AppendLine(string.Format("PortName:{0}", printerInfo.PortName)); 
       sb.AppendLine(string.Format("DriverName:{0}", printerInfo.DriverName)); 
       sb.AppendLine(string.Format("Comment:{0}", printerInfo.Comment)); 
       sb.AppendLine(string.Format("Location:{0}", printerInfo.Location)); 
       sb.AppendLine(string.Format("DevMode:{0}", printerInfo.DevMode)); 
       sb.AppendLine(string.Format("SepFile:{0}", printerInfo.SepFile)); 
       sb.AppendLine(string.Format("PrintProcessor:{0}", printerInfo.PrintProcessor)); 
       sb.AppendLine(string.Format("Datatype:{0}", printerInfo.Datatype)); 
       sb.AppendLine(string.Format("Parameters:{0}", printerInfo.Parameters)); 
       sb.AppendLine(string.Format("Attributes:{0}", printerInfo.Attributes)); 
       sb.AppendLine(string.Format("Priority:{0}", printerInfo.Priority)); 
       sb.AppendLine(string.Format("DefaultPriority:{0}", printerInfo.DefaultPriority)); 
       sb.AppendLine(string.Format("StartTime:{0}", printerInfo.StartTime)); 
       sb.AppendLine(string.Format("UntilTime:{0}", printerInfo.UntilTime)); 
       sb.AppendLine(string.Format("Status:{0}", printerInfo.Status)); 
       sb.AppendLine(string.Format("Jobs:{0}", printerInfo.Jobs)); 
       sb.AppendLine(string.Format("AveragePpm:{0}", printerInfo.AveragePpm)); 
       Console.WriteLine(sb.ToString()); 
      } 

      Console.ReadLine(); 
     } 
    } 

    class PrintSpoolerApi 
    { 
     [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)] 
     public static extern bool OpenPrinter(
      [MarshalAs(UnmanagedType.LPTStr)] 
      string printerName, 
      out IntPtr printerHandle, 
      PrinterDefaults printerDefaults); 

     [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)] 
     public static extern bool GetPrinter(
      IntPtr printerHandle, 
      int level, 
      IntPtr printerData, 
      int bufferSize, 
      ref int printerDataSize); 

     [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)] 
     public static extern bool ClosePrinter(
      IntPtr printerHandle); 

     [StructLayout(LayoutKind.Sequential)] 
     public struct PrinterDefaults 
     { 
      public IntPtr pDatatype; 
      public IntPtr pDevMode; 
      public int DesiredAccess; 
     } 

     public enum PrinterProperty 
     { 
      ServerName, 
      PrinterName, 
      ShareName, 
      PortName, 
      DriverName, 
      Comment, 
      Location, 
      PrintProcessor, 
      Datatype, 
      Parameters, 
      Attributes, 
      Priority, 
      DefaultPriority, 
      StartTime, 
      UntilTime, 
      Status, 
      Jobs, 
      AveragePpm 
     }; 

     public struct PrinterInfo2 
     { 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string ServerName; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string PrinterName; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string ShareName; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string PortName; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string DriverName; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string Comment; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string Location; 
      public IntPtr DevMode; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string SepFile; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string PrintProcessor; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string Datatype; 
      [MarshalAs(UnmanagedType.LPTStr)] 
      public string Parameters; 
      public IntPtr SecurityDescriptor; 
      public uint Attributes; 
      public uint Priority; 
      public uint DefaultPriority; 
      public uint StartTime; 
      public uint UntilTime; 
      public uint Status; 
      public uint Jobs; 
      public uint AveragePpm; 
     } 

     public static PrinterInfo2 GetPrinterProperty(string printerUncName) 
     { 
      var printerInfo2 = new PrinterInfo2(); 

      var pHandle = new IntPtr(); 
      var defaults = new PrinterDefaults(); 
      try 
      { 
       //Open a handle to the printer 
       bool ok = OpenPrinter(printerUncName, out pHandle, defaults); 

       if (!ok) 
       { 
        //OpenPrinter failed, get the last known error and thrown it 
        throw new Win32Exception(Marshal.GetLastWin32Error()); 
       } 

       //Here we determine the size of the data we to be returned 
       //Passing in 0 for the size will force the function to return the size of the data requested 
       int actualDataSize = 0; 
       GetPrinter(pHandle, 2, IntPtr.Zero, 0, ref actualDataSize); 

       int err = Marshal.GetLastWin32Error(); 

       if (err == 122) 
       { 
        if (actualDataSize > 0) 
        { 
         //Allocate memory to the size of the data requested 
         IntPtr printerData = Marshal.AllocHGlobal(actualDataSize); 
         //Retrieve the actual information this time 
         GetPrinter(pHandle, 2, printerData, actualDataSize, ref actualDataSize); 

         //Marshal to our structure 
         printerInfo2 = (PrinterInfo2)Marshal.PtrToStructure(printerData, typeof(PrinterInfo2)); 
         //We've made the conversion, now free up that memory 
         Marshal.FreeHGlobal(printerData); 
        } 
       } 
       else 
       { 
        throw new Win32Exception(err); 
       } 

       return printerInfo2; 
      } 
      finally 
      { 
       //Always close the handle to the printer 
       ClosePrinter(pHandle); 
      } 
     } 
    } 
} 

Vous pouvez récupérer encore plus de détails à partir de l'API, si nécessaire.

+0

J'ai utilisé les 2 méthodes ci-dessus qui interroge le WMI mais parfois il ne donne pas d'informations précises. MSDN indique que l'état d'une imprimante est déterminé par l'état du travail d'impression, il ne peut pas afficher les informations les plus précises jusqu'à ce qu'il essaie d'imprimer. Mais tout ce dont j'ai besoin est de savoir si l'imprimante est en ligne ou hors ligne, et je vois que Windows affiche très précisément le statut de son imprimante ajoutée localement ou à distance sous "Périphériques et imprimantes". Est-il possible d'accéder à ce statut Windows via le code C#? aussi j'apprends encore et je ne comprends pas l'API Spooler d'impression avez-vous plus de ressources là-dessus? – Zerone

+0

Édité le message principal pour inclure un exemple rapide – fletcher

+0

@Zerone - Est-ce que cette aide, ou avez-vous trouvé une autre façon de le faire? – fletcher

3

WMI est l'Utilisation de l'option commune pour ce genre de tâche ...

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer"); 

       foreach (ManagementObject printer in searcher.Get()) 
       { 
        string printerName = printer["Name"].ToString().ToLower(); 
        Console.WriteLine("Printer :" + printerName); 
        PrintProps(printer, "Status"); 
        PrintProps(printer, "PrinterState"); 
        PrintProps(printer, "PrinterStatus"); 


       } 

} 

static void PrintProps(ManagementObject o, string prop)  
{   
     try { Console.WriteLine(prop + "|" + o[prop]); 
     }   
     catch (Exception e) 
     { 
      Console.Write(e.ToString()); 
     }  
} 
+0

Merci beaucoup pour la réponse. cette méthode a fonctionné avec succès mais parfois elle ne donne pas le statut le plus précis depuis le statut qu'elle a déterminé par les informations de travail d'impression. MSDN le dit .. mais je me demande comment Windows 7 trouve très exactement le statut d'une imprimante, que ce soit en ligne ou hors ligne et est-il possible d'obtenir ce statut que Windows affiche; à travers le code C#? – Zerone

+0

@Zerone: Avez-vous oublié d'upvoter cette réponse? –

+0

@pipitas: pas que j'ai oublié je n'ai pas remarqué le vote up; rejoint très récemment. et merci d'avoir signalé cela. – Zerone

3

Statut en ligne

Considérez cet article CodeProject intitulé "How To Check If Your Printer Is Connected" L'exemple de code utilise WMI et le System.Management espace de nommage.

Copier/coller:

ManagementScope scope = new ManagementScope(@"\root\cimv2"); 
    scope.Connect(); 

    // Select Printers from WMI Object Collections 

    ManagementObjectSearcher searcher = new 
    ManagementObjectSearcher("SELECT * FROM Win32_Printer"); 

    string printerName = ""; 
    foreach (ManagementObject printer in searcher.Get()) 
    { 
    printerName = printer["Name"].ToString().ToLower(); 
    if (printerName.Equals(@"hp deskjet 930c")) 
    { 
    Console.WriteLine("Printer = " + printer["Name"]); 
    if (printer["WorkOffline"].ToString().ToLower().Equals("true")) 
    { 
     // printer is offline by user 

     Console.WriteLine("Your Plug-N-Play printer is not connected."); 
    } 
    else 
    { 
     // printer is not offline 

     Console.WriteLine("Your Plug-N-Play printer is connected."); 
    } 
    } 
    } 
    } 
+0

Merci beaucoup pour la réponse. cette méthode a également fonctionné avec succès mais parfois elle ne donne pas le statut le plus précis depuis le statut qu'elle a déterminé par les informations de travail d'impression. MSDN le dit .. mais je me demande comment Windows 7 trouve très exactement le statu d'une imprimante que ce soit en ligne ou hors ligne et est-il possible que nous puissions obtenir ce statut que Windows affiche; à travers le code C#? – Zerone

+0

@Zerone: même si vous avez des questions ouvertes, je pense que cette réponse mérite aussi un upvote. –

+0

@pipitas: merci de souligner le vote up. – Zerone

Questions connexes