Я собираюсь спросить и ответить на свой вопрос. Я бы подумал, что нужно создать нулевой принтер, это не редкость, но я потратил слишком долго на поиски и сборку бит и кусочков, прежде чем у меня появилось рабочее решение. Я нашел много ответов на создание нулевого принтера через графический интерфейс Windows, но информация о его программном обеспечении была относительно скудной и разбросана. Надеюсь, мой ответ или лучшие предложения, которые он изложит, сэкономят некоторое время для другого бедного шмо.Как программно создать нулевой принтер для Windows?
ответ
Это «работало для меня». Я предполагаю, что есть более элегантный способ достижения этого, и я ожидаю любое количество предложений по улучшению/исправлению кода, но я не смог найти краткий полный ответ на то, что, как я думал, было бы относительно общей потребностью. У меня был довольно конкретное требование, очевидно, этот код может быть обобщен, надлежащая обработка ошибок может быть добавлена и т.д.
//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);
}
}
}
Эй @mickeyf, вы выяснили какой-либо другой способ сделать это или улучшить свой код? – jNewbie
@jnewbie У меня было много на плите, и это оказалось «достаточно хорошим» для ситуации, поэтому я больше не тратил на нее больше времени. Надеюсь, это поможет вам. Я не буду подвергать сомнению ваши мотивы. – mickeyf
Хахаха, спасибо! У вас есть код для получения данных, отправленных на созданный принтер? – jNewbie
- 1. Программно установить принтер для обхода стеллажа Windows
- 2. Как создать виртуальный принтер?
- 3. Как программно искать принтер в Active Directory
- 4. Программно заставить принтер печатать дубликаты
- 5. Windows Azure - создать подписку программно
- 6. Windows IoT - USB-принтер
- 7. Как создать учетную запись службы Windows программно
- 8. Как создать нулевой символ?
- 9. Изменение Google Chrome по умолчанию принтер, программно
- 10. Печать PDF в принтер программно C#
- 11. Как создать GPO программно?
- 12. Как имитировать медленный принтер в Windows XP?
- 13. Как переименовать принтер на C++ в Windows?
- 14. Как создать имитируемый принтер в Python?
- 15. Windows дублирующий принтер с настраиваемым именем
- 16. Программно изменяя принтер назначения для элемента управления WinForms WebBrowser
- 17. Как программно печатать на принтер этикеток в Windows 7 с помощью C#
- 18. Как смоделировать принтер (IPP)
- 19. Как создать NSTextField программно?
- 20. Как создать sitecollection программно
- 21. Как создать ColorStateList программно?
- 22. Как создать изображение программно
- 23. Как программно извлечь LiveID для Windows Phone?
- 24. Как программно создать паузу в приложении Windows Service?
- 25. Как создать DrawerLayout программно
- 26. Windows 8.1 печать непосредственно на принтер
- 27. Как создать папку фотоальбома в Windows Phone 8 Программно
- 28. Как отправить контрольные символы на принтер Windows в Crystal Reports?
- 29. Как перезапустить принтер катушки?
- 30. Как создать runkit для Windows?
Хотя это вполне приемлемо, чтобы спросить и ответить на свой вопрос здесь, вопрос, который вы Спрашиваете * должны соответствовать те же стандарты качества, что и любой другой вопрос. Это не так. Пожалуйста, отредактируйте, чтобы четко объяснить проблему, которую вы пытаетесь решить, и задайте четко сформулированный вопрос, который затем может ответить на ваш ответ. –
Приношу свои извинения. Я думал, что сам титул четко сформулировал вопрос. Возможно, я слишком близко к нему, чтобы понять, как это не так? Предложите мне определенную критику, и я сделаю все возможное, чтобы улучшить ее. – mickeyf
Удалите все содержимое вопроса и добавьте причину, по которой вам необходимо создать «нулевой принтер». В настоящее время почта содержит только «поиск alot» и «I am awesome» текст, и нет ясной причины, почему это можно было бы сделать. (Ваш вопрос, скорее всего, по теме, когда вы получите его в форме). –