檢索

2012-11-05 16 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); 
     } 
    } 
}