作为我项目的一部分,我正在学习如何使用新的“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 )
}
最佳答案
[Namespace.Class]::Method()
表示对static method的调用。类型定义中的
OpenPrinterHandle()
方法是instance method。要更改行为,只需在方法签名中引入
static
关键字即可:public static IntPtr OpenPrinterHandle(string printerName)
然后您应该能够:
[OpenPrinter1.Program1]::OpenPrinterHandle($printername)