作为我项目的一部分,我正在学习如何使用新的“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 )
    }

最佳答案

This syntax:

[Namespace.Class]::Method()

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

要更改行为,只需在方法签名中引入 static 关键字即可:
public static IntPtr OpenPrinterHandle(string printerName)

然后您应该能够:
[OpenPrinter1.Program1]::OpenPrinterHandle($printername)

09-27 03:25