openprinter与winspool.drv无法正常工作

时间:2015-06-25 10:32:26

标签: powershell printing

作为我项目的一部分,我正在学习如何使用" winspool.drv"来处理打印机。和" PRINTUI.DLL,PrintUIEntry"我是新来的。我正在为这个项目使用powershell。问题是当我尝试使用openprinter方法获取打印机句柄时,我的代码会抛出错误 错误:方法调用失败,因为[OpenPrinter1.Program1]不包含名为' OpenPrinterHandle'的方法。

代码:

$code = @'
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Runtime.InteropServices;
  using System.IO; 

   namespace OpenPrinter1
    {
   public class Program1
    {
    [DllImport("winspool.drv", EntryPoint = "OpenPrinter", SetLastError =true)] 
    internal static extern bool OpenPrinter(string pPrinterName, ref IntPtr   phPrinter, PRINTER_DEFAULTS pDefault);

    [DllImport("winspool.drv", EntryPoint = "ClosePrinter", SetLastError = true)]
  internal static extern int ClosePrinter(IntPtr hPrinter);

  [StructLayout(LayoutKind.Sequential)]
  public class PRINTER_DEFAULTS
  {
  public string pDatatype;
  public IntPtr pDevMode;
  public int DesiredAccess;
  }

 public struct OpenPrinterAccessCodes
{
  public const int DELETE = 0x10000; // DELETE - Allowed to delete printers
  public const int READ_CONTROL = 0x20000; // READ_CONTROL - 
  public const int WRITE_DAC = 0x40000; // WRITE_DAC - 
  public const int WRITE_OWNER = 0x80000; // WRITE_OWNER - 
  public const int SERVER_ACCESS_ADMINISTER = 0x1;
  public const int SERVER_ACCESS_ENUMERATE = 0x2;
  public const int PRINTER_ACCESS_ADMINISTER = 0x4;
  public const int PRINTER_ACCESS_USE = 0x8;
  public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
  public const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
  public const int SERVER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE);

    public const int MAX_PORTNAME_LEN = 64;
    public const int MAX_NETWORKNAME_LEN = 49;
    public const int MAX_SNMP_COMMUNITY_STR_LEN = 33;
    public const int MAX_QUEUENAME_LEN = 33;
    public const int MAX_IPADDR_STR_LEN = 16;

    public const int ERROR_INSUFFICIENT_BUFFER = 122;
    public const int ERROR_INVALID_FLAGS = 1004;
    }
    public IntPtr OpenPrinterHandle(string printerName)
    {
    var def = new PRINTER_DEFAULTS { pDatatype = null, pDevMode = IntPtr.Zero, DesiredAccess = OpenPrinterAccessCodes.PRINTER_ALL_ACCESS };
    var hPrinter = IntPtr.Zero;
    if (!OpenPrinter(printerName, ref hPrinter, def))
    {
        var lastWin32Error = new Win32Exception(Marshal.GetLastWin32Error());

        throw lastWin32Error;
    }
    return hPrinter;
}
}
}
'@

 cls
  Add-Type -TypeDefinition $code -Language CSharp  


  if(!([OpenPrinter1.Program1]:: OpenPrinterHandle("hp LaserJet 1320 PCL 6 (Copy 1)")))
    {
    throw (New-Object componentmodel.win32Exception )
    }

1 个答案:

答案 0 :(得分:1)

This syntax

[Namespace.Class]::Method()

表示调用static method。您的类型定义中的OpenPrinterHandle()方法是instance method

要更改行为,只需在方法签名中引入static关键字:

public static IntPtr OpenPrinterHandle(string printerName)

然后你应该能够做到:

[OpenPrinter1.Program1]::OpenPrinterHandle($printername)