嗨,对于在 excel 上工作的打印方法,我需要像这样的打印机名称和端口名称:“打印机 On NE3”只是作为示例。问题是,我使用虚拟打印机并且端口不同,几乎每次我需要使用它时。
该程序需要在后台运行,因此打开对话框进行选择不是一个选项。我还尝试使用以下方法从 WMI 检索端口名称:
protected string FindPrinterWithPort(string printerName)
{
StringBuilder query = new StringBuilder();
query.Append("SELECT * FROM Win32_Printer ");
query.Append("WHERE DeviceID = \""+printerName+"\"");
ObjectQuery objectQuery = new ObjectQuery(query.ToString());
var searcher = new ManagementObjectSearcher(objectQuery);
foreach (ManagementObject mo in searcher.Get())
{
return printerName +" On "+ mo["PortName"];
}
return string.Empty;
}
我收到的端口名称为我提供了虚拟打印机程序的完整路径。我以前用下面的方法为excel更改打印机,我一直知道它们最终应该被更改,代码既不快也不好,但它工作了一段时间,直到我把它变成多线程并且它只是一个很大的封锁. 因为我需要锁定这些方法而不是更改 Windows 中的默认打印机。
private bool SetPrinterForExcel(string printerName){
string[] ports = new string[]{"Ne00:", "Ne01:", "Ne02:", "Ne03:", "Ne04:",
"Ne05:", "Ne06:", "Ne07:", "Ne08:",
"Ne09:", "Ne10:", "Ne11:", "Ne12:",
"Ne13:", "Ne14:", "Ne15:", "Ne16:",
"LPT1:", "LPT2:", "File:", "SMC100:"};
foreach (string port in ports)
{
string printerWithPort = printerName + " On " + port;
bool success = SetAndTestPrinter(printerWithPort);
if(success)
return true;
}
return false;
}
private bool SetAndTestPrinter(string printerWithPort)
{
try
{
excel.ActivePrinter = printerWithPort;
return true;
}
catch
{
return false;
}
}
任何想法如何检索端口,或者是否有办法从 WMI 查询中获取正确的端口。
提前致谢
编辑:
我没有得到它的工作,我现在所做的打印是更改 Windows 上的默认打印机,然后在我的 excel 对象上执行打印方法。我使用以下方法更改了它:
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);
我锁定它的方法并打印。我曾考虑过尝试锁定并保存 ActivePrinter,即使我相信性能也会一样糟糕。因为锁定会一直保留到更改默认打印机(有时需要长达 1 秒),所以在多线程环境中这是一个非常长的锁定。
string printernamewithPort = string.Empty;
lock (ActivePrinterLock)
{
SetDefaultPrinter(printername);
printernamewithPort = excel.ActivePrinter;
}
foreach (Worksheet worksheet in workbook.Worksheets)
{
worksheet.PageSetup.PaperSize = XlPaperSize.xlPaperA4;
worksheet.PageSetup.Orientation = XlPageOrientation.xlPortrait;
worksheet.PageSetup.FitToPagesWide = 1;
worksheet.PageSetup.FitToPagesTall = false;
worksheet.PrintOutEx(ActivePrinter: printernamewithPort,Collate: true, Preview: false, PrintToFile: false);
}
我不知道的是,如果默认打印机立即从另一个线程更改,如果它丢失了给虚拟打印机的端口。我没有对此进行适当的测试。在正常情况下,我的方法 FindPrinterWithPort 似乎可以工作。