C# 打印机(默认值pDefault); [DllImport(“winspool.drv”,EntryPoint=“ClosePrinter”)] 专用静态外部打印机(IntPtr hPrinter); 公共静态int AddLocalPort(字符串端口名) { 打印机_DEFAULTS def=新打印机_DEFAULTS(); def.pDatatype=null; def.pDevMode=IntPtr.Zero; def.DesiredAccess=1;//服务器访问管理 IntPtr hPrinter=IntPtr.Zero; int n=OpenPrinter(“,XcvMonitor本地端口”,参考HPPrinter,def); 如果(n==0) 返回Marshal.GetLastWin32Error(); 如果(!portName.EndsWith(“\0”)) portName+=“\0”;//必须是以null结尾的字符串 //必须以字节为单位获取大小。网络字符串由2字节字符组成 uint size=(uint)(portName.Length*2); //在HGlobal中分配内存以设置端口名 IntPtr portPtr=Marshal.AllocHGlobal((int)size); Copy(portName.ToCharArray(),0,portPtr,portName.Length); 不使用的单位; uint-xcvResult; XcvData(hPrinter,“AddPort”,portPtr,size,IntPtr.Zero,0,out NotUsedByUs,out xcvResult); 闭式打印机(hPrinter); 弗里赫全球元帅(portPtr); 返回(int)xcvResult; } 公共静态无效添加打印机(字符串打印机名称) { IntPtr mystrptr=新的IntPtr(0); IntPtr mysend2; 打印机_INFO_2 pi=新打印机_INFO_2(); pi.pServerName=“”; pi.ppintername=PrinterName; pi.pShareName=“NUL”; pi.pPortName=“NUL”; pi.pDriverName=“通用/仅限文本”; pi.pComment=“无评论”; pi.pLocation=“本地”; pi.pDevMode=mystrptr; pi.pSepFile=“”; pi.pPrintProcessor=“WinPrint”; pi.pDatatype=“原始”; pi.p参数=”; pi.pSecurityDescriptor=mystrptr; mysend2=AddPrinter(null,2,ref-pi); } } }

C# 打印机(默认值pDefault); [DllImport(“winspool.drv”,EntryPoint=“ClosePrinter”)] 专用静态外部打印机(IntPtr hPrinter); 公共静态int AddLocalPort(字符串端口名) { 打印机_DEFAULTS def=新打印机_DEFAULTS(); def.pDatatype=null; def.pDevMode=IntPtr.Zero; def.DesiredAccess=1;//服务器访问管理 IntPtr hPrinter=IntPtr.Zero; int n=OpenPrinter(“,XcvMonitor本地端口”,参考HPPrinter,def); 如果(n==0) 返回Marshal.GetLastWin32Error(); 如果(!portName.EndsWith(“\0”)) portName+=“\0”;//必须是以null结尾的字符串 //必须以字节为单位获取大小。网络字符串由2字节字符组成 uint size=(uint)(portName.Length*2); //在HGlobal中分配内存以设置端口名 IntPtr portPtr=Marshal.AllocHGlobal((int)size); Copy(portName.ToCharArray(),0,portPtr,portName.Length); 不使用的单位; uint-xcvResult; XcvData(hPrinter,“AddPort”,portPtr,size,IntPtr.Zero,0,out NotUsedByUs,out xcvResult); 闭式打印机(hPrinter); 弗里赫全球元帅(portPtr); 返回(int)xcvResult; } 公共静态无效添加打印机(字符串打印机名称) { IntPtr mystrptr=新的IntPtr(0); IntPtr mysend2; 打印机_INFO_2 pi=新打印机_INFO_2(); pi.pServerName=“”; pi.ppintername=PrinterName; pi.pShareName=“NUL”; pi.pPortName=“NUL”; pi.pDriverName=“通用/仅限文本”; pi.pComment=“无评论”; pi.pLocation=“本地”; pi.pDevMode=mystrptr; pi.pSepFile=“”; pi.pPrintProcessor=“WinPrint”; pi.pDatatype=“原始”; pi.p参数=”; pi.pSecurityDescriptor=mystrptr; mysend2=AddPrinter(null,2,ref-pi); } } },c#,windows,printers,C#,Windows,Printers,这个“为我工作”。我想有一种更优雅的方法来实现这一点,我希望有很多改进/纠正代码的建议,但我无法找到一个简洁完整的答案,来回答我认为相对普遍的需求。我有一个相当具体的要求,很明显,这段代码可以通用化,可以添加适当的错误处理,等等 //pd is a PrintDocument. used like: PrintController printController = new StandardPrintController(); pd.PrintController = printControl

这个“为我工作”。我想有一种更优雅的方法来实现这一点,我希望有很多改进/纠正代码的建议,但我无法找到一个简洁完整的答案,来回答我认为相对普遍的需求。我有一个相当具体的要求,很明显,这段代码可以通用化,可以添加适当的错误处理,等等

//pd is a PrintDocument. used like:

PrintController printController = new StandardPrintController();
pd.PrintController = printController;

NullPrinter np = new NullPrinter();                
if (!np.NullPortExists())
{
   np.CreateNullPort();
}

if (!np.NullPrinterExists())
{
    np.CreateNullPrinter();
}

pd.PrinterSettings.PrinterName = "NUL_PRINTER";


/*********************************************/ 
using System;
using System.Management; // This must also be added as a reference
using System.Drawing.Printing;
using System.Runtime.InteropServices;

namespace YourFavoriteNamespace
{
    //
    // This helper class has methods to determine whether a 'Nul Printer' exists,
    // and to create a null port and null printer if it does not.
    //
    public class NullPrinter
    {
    // Printer port management via Windows GUI (Windows 7, probably same in other versions):
    // 
    //      Go to printers & devices
    //      Select any printer
    //      Click on Print server properties
    //      Select Ports tab
    //      Add or remove (local) port
    //      To remove a local port, if "in use", stop and restart the print spooler service.
    //      It seems that the most recently used port will be "in use" until the system restarts,
    //      or until another port is used.
    //      A port may also be added when adding a printer.
    //      Valid names for a Null port appear to be NUL, NULL, NUL: - all case insensitive. 

    public bool NullPortExists()
    {
        for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
        {
           string printerName = PrinterSettings.InstalledPrinters[i];
           string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
           ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
           ManagementObjectCollection coll = searcher.Get();
           foreach (ManagementObject printer in coll)
           {
               string pName = printer["PortName"].ToString();
               if (pName.Equals("NULL", StringComparison.InvariantCultureIgnoreCase) ||
                pName.Equals("NUL", StringComparison.InvariantCultureIgnoreCase) ||
                pName.Equals("NUL:", StringComparison.InvariantCultureIgnoreCase))
               {
                return true;
               }
           }
        }
        return false;
    }

    // The application that uses this requires a printer specifically named "NUL_PRINTER"
    public bool NullPrinterExists()
    {
        for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
        {
            if (PrinterSettings.InstalledPrinters[i] == "NUL_PRINTER")
            {
                return true;
            }
        }
        return false;
    }

    public bool CreateNullPort()
    {
        return Winspool.AddLocalPort("NUL") == 0 ? true : false;
    }

    public void CreateNullPrinter()
    {
        Winspool.AddPrinter("NUL_PRINTER");
    }

}
/*********************************************************/
    //
    // This Winspool class was mostly borrowed and adapted 
    // from several different people's blog posts, 
    // the links to which I have lost. 
    // Thank you, whoever you are.
    //
    public static class Winspool
    {
        [StructLayout(LayoutKind.Sequential)]
        private class PRINTER_DEFAULTS
        {
            public string pDatatype;
            public IntPtr pDevMode;
            public int DesiredAccess;
        }

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        static extern IntPtr AddPrinter(string pName, uint Level, [In] ref PRINTER_INFO_2 pPrinter);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct PRINTER_INFO_2
        {
            public string pServerName,
              pPrinterName,
                  pShareName,
                  pPortName,
                  pDriverName,
                  pComment,
                  pLocation;
            public IntPtr pDevMode;
            public string pSepFile,
                  pPrintProcessor,
                  pDatatype,
                  pParameters;
            public IntPtr pSecurityDescriptor;
            public uint Attributes,
                  Priority,
                  DefaultPriority,
                  StartTime,
                  UntilTime,
                  Status,
                  cJobs,
                  AveragePPM;
        }

        [DllImport("winspool.drv", EntryPoint = "XcvDataW", SetLastError = true)]
        private static extern bool XcvData(
            IntPtr hXcv,
            [MarshalAs(UnmanagedType.LPWStr)] string pszDataName,
            IntPtr pInputData,
            uint cbInputData,
            IntPtr pOutputData,
            uint cbOutputData,
            out uint pcbOutputNeeded,
            out uint pwdStatus);

        [DllImport("winspool.drv", EntryPoint = "OpenPrinterA",  SetLastError = true)]
        private static extern int OpenPrinter(
            string pPrinterName,
            ref IntPtr phPrinter,
            PRINTER_DEFAULTS pDefault);

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

        public static int AddLocalPort(string portName)
        {
            PRINTER_DEFAULTS def = new PRINTER_DEFAULTS();

            def.pDatatype = null;
            def.pDevMode = IntPtr.Zero;
            def.DesiredAccess = 1; //Server Access Administer

            IntPtr hPrinter = IntPtr.Zero;

            int n = OpenPrinter(",XcvMonitor Local Port", ref hPrinter, def);
            if (n == 0)
            return Marshal.GetLastWin32Error();

            if (!portName.EndsWith("\0"))
            portName += "\0"; // Must be a null terminated string

            // Must get the size in bytes. .NET strings are formed by 2-byte characters
            uint size = (uint)(portName.Length * 2);

            // Alloc memory in HGlobal to set the portName
            IntPtr portPtr = Marshal.AllocHGlobal((int)size);
            Marshal.Copy(portName.ToCharArray(), 0, portPtr, portName.Length);

            uint NotUsedByUs;
            uint xcvResult; 

            XcvData(hPrinter, "AddPort", portPtr, size, IntPtr.Zero, 0,  out NotUsedByUs, out xcvResult);

            ClosePrinter(hPrinter);
            Marshal.FreeHGlobal(portPtr);

            return (int)xcvResult;
        }

        public static void AddPrinter(string PrinterName)
        {
          IntPtr mystrptr = new IntPtr(0);    
          IntPtr mysend2;
          PRINTER_INFO_2 pi = new PRINTER_INFO_2();

          pi.pServerName =  "";
          pi.pPrinterName = PrinterName;
          pi.pShareName = "NUL";
          pi.pPortName = "NUL";
          pi.pDriverName = "Generic / Text Only";
          pi.pComment = "No Comment";
          pi.pLocation = "Local";
          pi.pDevMode = mystrptr;
          pi.pSepFile = "";
          pi.pPrintProcessor = "WinPrint";
          pi.pDatatype = "RAW";
          pi.pParameters = "";
          pi.pSecurityDescriptor = mystrptr;
          mysend2 = AddPrinter(null,2, ref pi);                    
        }
    }

}
//pd是一个打印文档。用法如下:
PrintController PrintController=新标准PrintController();
pd.PrintController=PrintController;
NullPrinter np=新的NullPrinter();
如果(!np.NullPortExists())
{
np.CreateNullPort();
}
如果(!np.NullPrinterExists())
{
np.CreateNullPrinter();
}
pd.PrinterSettings.PrinterName=“NUL_打印机”;
/*********************************************/ 
使用制度;
使用System.Management;//这也必须作为参考添加
使用系统、绘图、打印;
使用System.Runtime.InteropServices;
命名空间YourFavoriteNamespace
{
//
//此帮助器类具有确定“Nul打印机”是否存在的方法,
//并创建空端口和空打印机(如果没有)。
//
公共类空打印机
{
//通过Windows GUI进行打印机端口管理(Windows 7,在其他版本中可能相同):
// 
//转到打印机和设备
//选择任意打印机
//单击打印服务器属性
//选择端口选项卡
//添加或删除(本地)端口
//要删除本地端口(如果“正在使用”),请停止并重新启动后台打印程序服务。
//在系统重新启动之前,最近使用的端口似乎将处于“使用中”,
//或者直到使用另一个端口。
//添加打印机时也可以添加端口。
//空端口的有效名称应为NUL、Null、NUL:-不区分大小写。
公共bool NullPortExists()
{
对于(int i=0;i