2010-07-19 2 views
3

LAN에서는 일반적으로 프린터가 공유되며 Windows의 "원격 프린터 추가"를 통해 LAN의 이러한 공유 컴퓨터를 시스템에 추가 할 수 있습니다. 이처럼 추가 된 프린터 목록과 C#을 통해 온라인 상태 및 프린터 설정을 가져오고 싶습니다. 추가 프린터 목록은 다음을 통해 얻을 수 있습니다.LAN에 프린터가 연결된 컴퓨터 이름 및 IP를 얻는 방법

System.Drawing.Printing.PrinterSettings.InstalledPrinters 

이 코드를 통해 추가 프린터 목록을 콤보 상자로 가져올 수 있습니다. 문제는 각 프린터의 온라인 상태를 얻는 방법과 C# 코드를 통해 가능한 다른 설정을 얻는 것입니다. 도와주세요.

+0

Jonathan, fletcher 및 p.campbell (30 분 이내 일부)이 훌륭하고 자세한 대답을 얻었습니다. 나는 당신이 더 많은 것을 요구하기 전에 당신이 그들의 노력을 upvote하는 것을 잊어 버렸을 것이라고 확신한다. 나는 나 자신이 투표를 한 번 보면서 너무 upvote 할 것이다. –

답변

2

WMI에 대한 대안으로, 당신은 프린터에 대한 자세한 정보를 수집하기 위해 Print Spooler API를 사용할 수 있습니다. API의 P/Invoke 서명은 대부분 http://www.pinvoke.net에 있습니다.

열기 프린터에 대한 핸들 : http://www.pinvoke.net/default.aspx/winspool.OpenPrinter

프린터 정보를 수집합니다 : http://www.pinvoke.net/default.aspx/winspool.GetPrinterData

편집 :

신속하게 함께 당신이 요청에 따라, PrintSpoolerApi에서 수집 할 수 있습니다 무엇의 예를 밟았다.

PrintSpoolerAPIExample :

새 콘솔 프로젝트를 만들고 (추론을 입력하기 때문에, 위의 .NET 3.5)이 함께 Program.cs에있는 모든 코드를 대체, 시스템에서 사용할 수있는 각 프린터의 프린터 세부 사항 (로컬 또는 네트워크로 연결된)이 콘솔에 인쇄됩니다. 상태 값은 관심있는 것입니다. "준비"상태 코드는 0입니다. 프린터를 비활성화하고 네트워크로 연결된 프린터에 대한 네트워크 연결을 비활성화하여 상태 변화를 확인할 수 있습니다.

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); 
      } 
     } 
    } 
} 

필요한 경우 API에서 더 많은 정보를 검색 할 수 있습니다.

+0

위의 두 가지 방법을 사용하여 WMI를 쿼리하지만 때로는 정확한 정보를 제공하지 않습니다. MSDN에서는 프린터의 상태가 인쇄 작업 상태에 의해 결정되기 때문에 인쇄를 시도 할 때까지 가장 정확한 정보를 표시 할 수 없다고 말합니다. 하지만 필자가 필요로하는 것은 프린터가 온라인인지 오프라인인지를 확인하는 것이며, Windows는 추가 된 프린터의 상태를 로컬 또는 원격으로 "장치 및 프린터"아래에 정확하게 표시합니다. 어쨌든 C# 코드를 통해 해당 Windows 상태에 액세스 할 수 있습니까? 또한 나는 여전히 배우고있어 인쇄 Spooler API에 대해 더 많은 리소스가 있다는 것을 이해하지 못합니까? – Zerone

+0

빠른 게시글을 포함하도록 기본 게시물을 편집했습니다. – fletcher

+0

@Zerone - 도움이 되었습니까? 아니면 다른 방법을 찾았습니까? – fletcher

3

WMI는 작업의 종류에 대한 일반적인 옵션 사용 ...

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

답변 해 주셔서 감사합니다. 이 방법은 성공적으로 수행되었지만 때로는 인쇄 작업 정보에 의해 결정된 상태 이후로 가장 정확한 상태를 제공하지 않습니다. MSDN은 그렇게 말합니다. 그러나 Windows 7이 프린터의 상태를 온라인 또는 오프라인으로 정확하게 파악하고 Windows가 표시하는 상태를 얻을 수있는 방법을 찾는 방법에 대해 궁금합니다. C# 코드를 통해? – Zerone

+0

@ Zerone :이 대답을 upvote하는 것을 잊었습니까? –

+0

@pipitas : 나는 투표를하지 못했다는 것을 잊지 않았다. 아주 최근에 합류했습니다. 그리고 그것을 지적 해 주셔서 감사합니다. – Zerone

3

온라인 상태

자격이 CodeProject의 문서를 고려 "How To Check If Your Printer Is Connected는" 샘플 코드는 WMI와 System.Management를 사용 네임 스페이스. 붙여 넣기

복사/:

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

답변 해 주셔서 감사합니다. 이 방법도 성공적으로 수행되었지만 때로는 인쇄 작업 정보에 의해 결정된 상태 때문에 가장 정확한 상태를 제공하지 않습니다. MSDN은 그렇게 말합니다.하지만 Windows 7이 프린터의 상태를 온라인 또는 오프라인으로 매우 정확하게 찾아내는 방식과 Windows가 표시하는 상태를 얻을 수있는 방법을 찾는 방법에 대해 궁금합니다. C# 코드를 통해? – Zerone

+0

@ Zerone : 몇 가지 질문이 남아 있더라도이 대답은 upvote를받을 자격이 있다고 생각합니다. –

+0

@pipitas : 위로 투표 해 주셔서 감사합니다. – Zerone

관련 문제