1

こんにちは、印刷方法がExcelで機能するには、例として、「プリンターの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