• 【转载】使用WIN32API获取打印机


    使用WIN32API获取打印机

    转来转去,又回到WIN32API上来了,无奈啊。。。。。。怪不得C++依然这么吃香 啊。。。。。

    .Net给我们提供了DllImport来操作非托管的DLL(发现C#如此的强啊~~~~暗自偷笑)。

    主要使用到winspool.drv中的EnumPrinters函数,代码如下:

     [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)] 
      [
    return: MarshalAs(UnmanagedType.Bool)] 
      
    private static extern bool EnumPrinters ([MarshalAs(UnmanagedType.U4)] PRINTER_ENUM flags, 
       [MarshalAs(UnmanagedType.LPStr)] 
    string sName, 
       
    uint iLevel, 
       IntPtr pPrinterDesc, 
       
    uint iSize, 
       [MarshalAs(UnmanagedType.U4)] 
    ref uint iNeeded, 
       [MarshalAs(UnmanagedType.U4)] 
    ref uint iReturned 
       ); 


    说明:Marshal属性提供了对托管代码与非托管代码见数据封送。

    EnumPrinters 的 WIN32 API的定义如下: 

    BOOL EnumPrinters(
      DWORD Flags,         
    // printer object types
      LPTSTR Name,         // name of printer object
      DWORD Level,         // information level
      LPBYTE pPrinterEnum, // printer information buffer
      DWORD cbBuf,         // size of printer information buffer
      LPDWORD pcbNeeded,   // bytes received or required
      LPDWORD pcReturned   // number of printers enumerated
    );

    问题又来啦,EnumPrinters通过Level来获取PRINTER_INFO,而能获得打印机驱动的是PRINTER_INFO_2,而C#中又没有PRINTER_INFO_2结构,偶又开始晕了。。。。。

    查了半天资料,网上基本上都是PRINTER_INFO_1的定义,而PRINTER_INFO_2不同与PRINTER_INFO_1,其中还包括DEVMODE结构,非托管的结构套结构,偶开始飘了~~~~

    最后发现与其在C#中定义结构来对应非托管的结构,还不如直接用类来替代。所以定义了两个类

    PRINTER_INFO_2以及DEVMODE(注:由于PRINTER_INFO_2中只用到了DEVMODE结构来接收打印机驱动的信息,所以只定义了这个类,对于其他类都没有做具体实现)。

    在PRINTER_INFO_2中,对于所有的DWORD类型数据,全部对应到Int32类型上面,而对于所有LPTSTR、LPDEVMODE以及PSECURITY_DESCRIPTOR一律对应到IntPtr指针类型。

    为了获取非托管中的数据,使用了一下函数获取打印机信息

    .

       PRINTER_INFO_2 pi 
    = new PRINTER_INFO_2(); 
        
    //把数据从非托管内存传送到到托管内存

        
    for(int i = 0; i < numPrinters; i++
       { 
          Marshal.PtrToStructure( prInfo, pi );   
    //prInfo是由上面EnumPrinters获得的打印机

          
    string driver = Marshal.PtrToStringAuto( pi.pDriverName );

          
    if ( printerdriver == "" || driver.ToLower().IndexOf( printerdriver ) != -1)
          {

               
    // 做相关处理

          }
          prInfo 
    = new IntPtr(prInfo.ToInt32() + Marshal.SizeOf(typeof(PRINTER_INFO_2))); // 获取下一个打印机信息段开始
       }
    .


    问题至此基本解决。但C#中对非托管函数的调用,以及相互之间的数据封装还是一个比较难的地方,有空还需要整理一下。

  • 相关阅读:
    一个简单的空间配置器
    【转】c++中placement new操作符
    类的operator new与operator delete的重载【转】
    STL中常用的c++语法
    java编程思想-多态
    java编程思想-复用类(2)
    java编程思想-复用类
    import与require的区别
    gulp插件
    gulp-gulpfile.js语法说明
  • 原文地址:https://www.cnblogs.com/fx2008/p/2240911.html
Copyright © 2020-2023  润新知