C#在Windows打印机管理中删除打印机端口
我目前正在为Windows打印机管理编写一个助手类(包装器) 目前,我能够创建和删除打印机对象 在接下来的一个步骤中,我想对打印机端口执行相同的操作 目前,我正在使用以下代码在Windows打印机管理中创建一个新的打印机端口 1.)DLL导入C#在Windows打印机管理中删除打印机端口,c#,.net,printing,C#,.net,Printing,我目前正在为Windows打印机管理编写一个助手类(包装器) 目前,我能够创建和删除打印机对象 在接下来的一个步骤中,我想对打印机端口执行相同的操作 目前,我正在使用以下代码在Windows打印机管理中创建一个新的打印机端口 1.)DLL导入 [DllImport("winspool.drv")] private static extern bool OpenPrinter(string printerName, out IntPtr phPrinter, ref PrinterDefaults
[DllImport("winspool.drv")]
private static extern bool OpenPrinter(string printerName, out IntPtr phPrinter, ref PrinterDefaults printerDefaults);
[DllImport("winspool.drv")]
private static extern bool ClosePrinter(IntPtr phPrinter);
[DllImport("winspool.drv", CharSet = CharSet.Unicode)]
private static extern bool XcvDataW(IntPtr hXcv, string pszDataName, IntPtr pInputData, UInt32 cbInputData, out IntPtr pOutputData, UInt32 cbOutputData, out UInt32 pcbOutputNeeded, out UInt32 pdwStatus);
[DllImport("winspool.drv")]
private static extern bool OpenPrinter(string printerName, out IntPtr phPrinter, ref PrinterDefaults printerDefaults);
[DllImport("winspool.drv")]
private static extern bool ClosePrinter(IntPtr phPrinter);
[DllImport("winspool.drv", CharSet = CharSet.Unicode)]
private static extern bool XcvDataW(IntPtr hXcv, string pszDataName, IntPtr pInputData, UInt32 cbInputData, out IntPtr pOutputData, UInt32 cbOutputData, out UInt32 pcbOutputNeeded, out UInt32 pdwStatus);
2.)结构
/// <summary>
/// Defines the printer default settings like the access rights
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct PrinterDefaults
{
public IntPtr pDataType;
public IntPtr pDevMode;
public PrinterAccess DesiredAccess;
}
/// <summary>
/// Stores the port data for adding a new printer port
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct CreatePortData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string sztPortName;
public UInt32 dwVersion;
public UInt32 dwProtocol;
public UInt32 cbSize;
public UInt32 dwReserved;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 49)]
public string sztHostAddress;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string sztSNMPCommunity;
public UInt32 dwDoubleSpool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string sztQueue;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string sztIPAddress;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 540)]
public byte[] Reserved;
public UInt32 dwPortNumber;
public UInt32 dwSNMPEnabled;
public UInt32 dwSNMPDevIndex;
}
/// <summary>
/// Specifies identifiers to indicate the printer access
/// </summary>
internal enum PrinterAccess
{
ServerAdmin = 0x01,
ServerEnum = 0x02,
PrinterAdmin = 0x04,
PrinterUse = 0x08,
JobAdmin = 0x10,
JobRead = 0x20,
StandardRightsRequired = 0x000f0000,
PrinterAllAccess = (StandardRightsRequired | PrinterAdmin | PrinterUse)
}
//
///定义打印机默认设置,如访问权限
///
[StructLayout(LayoutKind.Sequential)]
内部结构PrinterDefaults
{
公共IntPtr数据类型;
公共IntPtr pDevMode;
公共印刷商准入要求准入;
}
///
///存储用于添加新打印机端口的端口数据
///
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
内部结构CreatePortData
{
[Marshallas(UnmanagedType.ByValTStr,SizeConst=64)]
公共字符串sztPortName;
公共UInt32 DW版本;
公共UInt32 DWT协议;
公共UInt32 cbSize;
保留公共UInt32 DWT;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=49)]
公共字符串sztHostAddress;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=33)]
公共字符串SZTSNMP社区;
公共UInt32双滑阀;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=33)]
公共字符串;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=16)]
公共字符串sztIPAddress;
[Marshallas(UnmanagedType.ByValArray,SizeConst=540)]
公共字节[]保留;
公共UInt32 dwPortNumber;
公共UInt32 DWSN禁用;
公共UInt32 dwSNMPDevIndex;
}
///
///指定用于指示打印机访问权限的标识符
///
内部枚举PrinterAccess
{
ServerAdmin=0x01,
ServerEnum=0x02,
PrinterAdmin=0x04,
PrinterUse=0x08,
JobAdmin=0x10,
JobRead=0x20,
标准权利要求=0x000f0000,
PrinterLaccess=(要求的标准权限| PrinterAdmin | PrinterUse)
}
3)方法
//
///将新打印机端口添加到windows打印管理
///
///端口的配置类型。例如,标准TCP/IP端口。
///
///
///
///当参数为null或空时发生
///将新TCP打印机端口添加到打印机管理失败时发生
公共静态void CreatePrinterPort(字符串配置类型、字符串端口名、PrinterPortType端口类型、字符串端点)
{
//验证
if(String.IsNullOrEmpty(configurationType))
抛出新ArgumentNullException(nameof(configurationType));
if(String.IsNullOrEmpty(portName))
抛出新ArgumentNullException(nameof(portName));
if(String.IsNullOrEmpty(端点))
抛出新ArgumentNullException(nameof(endpoint));
//打开“打印机管理”对话框
PrinterDefaults默认值=新的PrinterDefaults{DesiredAccess=PrinterAccess.ServerAdmin};
如果(!OpenPrinter(“,XcvMonitor”+配置类型,输出IntPtr printerHandle,参考默认值))
{
string message=string.Format(Resources.FailedToOpenPrinterManagement,configurationType);
抛出新的PrinterManagementHelperException(消息);
}
尝试
{
//定义端口属性
CreatePortData portData=新建CreatePortData
{
dwVersion=1,
dwProtocol=(uint)端口类型,
dwPortNumber=portType==PrinterPortType.Raw?9100u:515u,
dwReserved=0,
sztPortName=portName,
sztIPAddress=端点,
sztHostAddress=端点,
sztsnmpcomunity=“public”,
dwSNMPEnabled=1,
dwSNMPDevIndex=1
};
//将端口属性设置到指针中
uint size=(uint)Marshal.SizeOf(portData);
portData.cbSize=大小;
IntPtr pointer=Marshal.AllocHGlobal((int)size);
StructureToPtr(portData,指针,true);
尝试
{
//将端口添加到打印机管理
如果(!XcvDataW(打印机手柄,“添加端口”,指针,大小,输出IntPtr outputData,0,需要输出uint OUTPUT,输出uint状态))
抛出新的PrinterManagementHelperException(Resources.failedToadTcpPrinterPorttoPrinterManagement);
}
捕获(例外)
{
投掷;
}
最后
{
自由全局元帅(指针);
}
}
捕获(异常)
{
string message=string.Format(Resources.failedtoaddtcprinterport,
配置类型、端口名称、端口类型、端点);
抛出新的PrinterManagementHelperException(消息,异常);
}
最后
{
闭式打印机(打印机手柄);
}
}
我在上找到了以下主题。根据主题,我必须将'AddPort'参数更改为'DeletePort'。更改参数值不会从打印机管理中删除打印机端口。该方法返回的状态为13(十六进制:0x0000000d)。关于这个问题,数据似乎是无效的。当我想删除打印机端口时,有人知道如何设置数据吗
更新1
我发现上面代码示例中使用的端口数据结构仅用于添加打印机端口。我找到了一个关于这个的主题。还有另一个关于移除打印机端口的结构。我试图基于CreatePortData结构样本重建模型。我创建了以下结构
/// <summary>
/// Stores the port data for deleting an existing printer port
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct DeletePortData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string sztPortName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 49)]
public string sztName;
public UInt32 dwVersion;
public UInt32 dwReserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 540)]
public byte[] Reserved;
}
//
///存储用于删除现有打印机端口的端口数据
///
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
内部结构DeletePortData
{
[Marshallas(UnmanagedType.ByValTStr,SizeConst=64)]
公共字符串sztPortName;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=49)]
公共字符串sztName;
公共UInt32 DW版本;
保留公共UInt32 DWT;
[Marshallas(UnmanagedType.ByValArray,SizeConst=540)]
公共字节[
/// <summary>
/// Deletes an existing printer port from the printer management
/// </summary>
/// <param name="configurationType">The configuration type of the port. For example Standard TCP/IP Port.</param>
/// <param name="portName"></param>
public static void DeletePrinterPort(string configurationType, string portName)
{
// Validation
if (String.IsNullOrEmpty(configurationType))
throw new ArgumentNullException(nameof(configurationType));
if (String.IsNullOrEmpty(portName))
throw new ArgumentNullException(nameof(portName));
// Opens the printer management
PrinterDefaults defaults = new PrinterDefaults { DesiredAccess = PrinterAccess.ServerAdmin };
if (!OpenPrinter(",XcvMonitor " + configurationType, out IntPtr printerHandle, ref defaults))
{
string message = String.Format(Resources.FailedToOpenPrinterManagement, configurationType);
throw new PrinterManagementHelperException(message);
}
try
{
// Defines the port properties
DeletePortData portData = new DeletePortData
{
dwVersion = 1,
dwReserved = 0,
sztPortName = portName
};
// Sets the port properties into the pointer
uint size = (uint)Marshal.SizeOf(portData);
IntPtr pointer = Marshal.AllocHGlobal((int)size);
Marshal.StructureToPtr(portData, pointer, true);
try
{
// Deletes the port from the printer management
if (!XcvDataW(printerHandle, "DeletePort", pointer, size, out IntPtr outputData, 0, out uint outputNeeded, out uint status))
throw new PrinterManagementHelperException(Resources.FailedToDeletePrinterPortFromPrinterManagement);
}
catch (Exception)
{
throw;
}
finally
{
Marshal.FreeHGlobal(pointer);
}
}
catch (Exception exception)
{
string message = string.Format(Resources.FailedToDeletePrinterPort, configurationType, portName);
throw new PrinterManagementHelperException(message, exception);
}
finally
{
ClosePrinter(printerHandle);
}
}
[DllImport("winspool.drv")]
private static extern bool OpenPrinter(string printerName, out IntPtr phPrinter, ref PrinterDefaults printerDefaults);
[DllImport("winspool.drv")]
private static extern bool ClosePrinter(IntPtr phPrinter);
[DllImport("winspool.drv", CharSet = CharSet.Unicode)]
private static extern bool XcvDataW(IntPtr hXcv, string pszDataName, IntPtr pInputData, UInt32 cbInputData, out IntPtr pOutputData, UInt32 cbOutputData, out UInt32 pcbOutputNeeded, out UInt32 pdwStatus);
/// <summary>
/// Defines the printer default settings like the access rights
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct PrinterDefaults
{
public IntPtr pDataType;
public IntPtr pDevMode;
public PrinterAccess DesiredAccess;
}
/// <summary>
/// Stores the port data for deleting an existing printer port
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct DeletePortData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string sztPortName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 49)]
public string sztName;
public UInt32 dwVersion;
public UInt32 dwReserved;
}
/// <summary>
/// Specifies identifiers to indicate the printer access
/// </summary>
internal enum PrinterAccess
{
ServerAdmin = 0x01,
ServerEnum = 0x02,
PrinterAdmin = 0x04,
PrinterUse = 0x08,
JobAdmin = 0x10,
JobRead = 0x20,
StandardRightsRequired = 0x000f0000,
PrinterAllAccess = (StandardRightsRequired | PrinterAdmin | PrinterUse)
}
/// <summary>
/// Deletes an existing printer port from the printer management
/// </summary>
/// <param name="configurationType">The configuration type of the port. For example Standard TCP/IP Port.</param>
/// <param name="portName"></param>
public static void DeletePrinterPort(string configurationType, string portName)
{
// Validation
if (String.IsNullOrEmpty(configurationType))
throw new ArgumentNullException(nameof(configurationType));
if (String.IsNullOrEmpty(portName))
throw new ArgumentNullException(nameof(portName));
// Opens the printer management
PrinterDefaults defaults = new PrinterDefaults { DesiredAccess = PrinterAccess.ServerAdmin };
if (!OpenPrinter(",XcvMonitor " + configurationType, out IntPtr printerHandle, ref defaults))
{
string message = String.Format(Resources.FailedToOpenPrinterManagement, configurationType);
throw new PrinterManagementHelperException(message);
}
try
{
// Defines the port properties
DeletePortData portData = new DeletePortData
{
dwVersion = 1,
dwReserved = 0,
sztPortName = portName
};
// Sets the port properties into the pointer
uint size = (uint)Marshal.SizeOf(portData);
IntPtr pointer = Marshal.AllocHGlobal((int)size);
Marshal.StructureToPtr(portData, pointer, true);
try
{
// Deletes the port from the printer management
if (!XcvDataW(printerHandle, "DeletePort", pointer, size, out IntPtr outputData, 0, out uint outputNeeded, out uint status))
throw new PrinterManagementHelperException(Resources.FailedToDeletePrinterPortFromPrinterManagement);
}
catch (Exception)
{
throw;
}
finally
{
Marshal.FreeHGlobal(pointer);
}
}
catch (Exception exception)
{
string message = string.Format(Resources.FailedToDeletePrinterPort, configurationType, portName);
throw new PrinterManagementHelperException(message, exception);
}
finally
{
ClosePrinter(printerHandle);
}
}