检索

2012-11-05 18 views
5

在C#中我会得到安装在运行系统中所有的打印机驱动程序列表中的所有可用的打印机驱动程序(如添加打印机向导)的列表,就像在Windows "add printer" wizard检索

我已经能够列出已经安装了打印机,但是如何列出系统中可用的驱动程序?

+0

此向导不*不*列出已安装打印机驱动程序,它包括*可能*安装驱动程序。这种功能被安装在安装API中。从.NET很难使用,这个问题很讨厌。它通常不是一个简单的API。 http://msdn.microsoft.com/en-us/library/windows/hardware/ff553567%28v=vs.85%29.aspx –

+0

非常感谢您的回复。我想我宁愿避免... –

回答

0

此代码枚举安装打印机驱动程序:

public struct DRIVER_INFO_2 
{ 
    public uint cVersion; 
    [MarshalAs(UnmanagedType.LPTStr)] public string pName; 
    [MarshalAs(UnmanagedType.LPTStr)] public string pEnvironment; 
    [MarshalAs(UnmanagedType.LPTStr)] public string pDriverPath; 
    [MarshalAs(UnmanagedType.LPTStr)] public string pDataFile; 
    [MarshalAs(UnmanagedType.LPTStr)] public string pConfigFile; 
} 


public static class EnumeratePrinterDriverNames 
{ 
    [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern int EnumPrinterDrivers(String pName, String pEnvironment, uint level, IntPtr pDriverInfo, 
     uint cdBuf, ref uint pcbNeeded, ref uint pcRetruned); 

    public static IEnumerable<string> Enumerate() 
    { 
     const int ERROR_INSUFFICIENT_BUFFER = 122; 

     uint needed = 0; 
     uint returned = 0; 
     if (EnumPrinterDrivers(null, null, 2, IntPtr.Zero, 0, ref needed, ref returned) != 0) 
     { 
      //succeeds, but shouldn't, because buffer is zero (too small)! 
      throw new ApplicationException("EnumPrinters should fail!"); 
     } 

     int lastWin32Error = Marshal.GetLastWin32Error(); 
     if (lastWin32Error != ERROR_INSUFFICIENT_BUFFER) 
     { 
      throw new Win32Exception(lastWin32Error); 
     } 

     IntPtr address = Marshal.AllocHGlobal((IntPtr) needed); 
     try 
     { 
      if (EnumPrinterDrivers(null, null, 2, address, needed, ref needed, ref returned) == 0) 
      { 
       throw new Win32Exception(Marshal.GetLastWin32Error()); 
      } 

      var type = typeof (DRIVER_INFO_2); 
      IntPtr offset = address; 
      int increment = Marshal.SizeOf(type); 

      for (uint i = 0; i < returned; i++) 
      { 
       var di = (DRIVER_INFO_2) Marshal.PtrToStructure(offset, type); 
       offset += increment; 

       yield return di.pName; 
      } 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(address); 
     } 
    } 
}