1

嗨,对于在 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 似乎可以工作。

4

0 回答 0