收到COMException分配给Excel.Application.ActivePrinter时(

2019-10-17 16:52发布

我有一个功能,在其中我传递一个Microsoft.Office.Interop.Excel.Application实例。 该功能使用Windows内置的传真打印机或Microsoft XPS文档写入,将文件保存为TIFF图像。

然而,当我试图给应用程序的ActivePrinter属性,与下面的消息收到COMException抛出:

从HRESULT异常:0x800A03EC

下面的代码:

'Save the current default printer
Dim strDefaultPrinter As String = excelApp.ActivePrinter 

'Assign printer string constant to ActivePrinter - throws exception
excelApp.ActivePrinter = FAX_PRINTER

excelApp.ActiveWorkbook.PrintOutEx(, , , , , True, "c:\RestOfFilePath...") ' Print to file = true

'Reset the default printer
excelApp.ActivePrinter = strDefaultPrinter

所使用的打印机都确认安装/在注册表中。 类似的功能,需要一个Word应用程序级工作正常。 我是很新,COM相关的东西,我有一种感觉,这可能只是我在玩的Excel相关的无知,但我几乎可以找到任何谷歌搜索/计算器时,除了一个或两个老,解答有关本线程。 有几个,涉及到大量数据/大范围的,但不是ActivePrinter属性

编辑 - 答案,以M Patel的链接详细的小结:

Excel是挑剔设置它的ActivePrinter属性; 而不是单独的打印机名称的,它同时需要打印机和端口,例如,“传真上Ne01:”。 此端口应该可以从注册表,无论是在:

HKEY_CURRENT_USER \ SOFTWARE \微软\的Windows NT \ CURRENTVERSION \设备

要么

HKEY_LOCAL_MACHINE \ SOFTWARE \微软\的Windows NT \ CURRENTVERSION \设备

使用中的链接详细描述的方法,或在我的情况下,使用Microsoft.Win32.Registry.GetValue()。 后者将返回的东西线沿线的“WINSPOOL,Ne01:”。 串联该字符串的最后一部分上的方式打印机名称“上Ne01传真:”允许ActivePrinter属性来没有例外设置。

我还应该注意到,我的问题是在2010年发生的excel

Answer 1:

也许下面的链接将帮助? 它看起来像你分配给ActivePrinter属性事项名称的格式。

http://netindonesia.net/blogs/jimmy/archive/2011/02/25/how-to-change-the-active-printer-to-specific-printer-in-excel-using-net-and-how-在-赫克,可以-I-找到最合适的打印机的名称和端口的组合,也就是说,Excel的wants.aspx



Answer 2:

我有同样的例外,同时打印使用Excel互操作Excel的文档。

与MS Word: -

document.Application.ActivePrinter = "Brother MFC.. Printer"; // Works without exception

但是,使用MS Excel: -

document.Application.ActivePrinter = "Brother MFC.. Printer"; // throws COM exception

下面是一个通用的函数使用办公室互操作打印任何办公室(微软Word,MS Excel中,PS简报)文件。

    void PrintToPrinter(dynamic app, dynamic document, string printer, int numberOfCopies)
    {
        bool PrintToFile = false;

        // Trying to print document without activation throws print exception
        document.Activate();

        // The only way to change printer is to set the default printer of document or of application
        // Remember the active printer name to reset after printing document with intended printer
        oldPrinterName = document.Application.ActivePrinter;

        for (int retry = 0; retry < retryLimit; retry++)
        {
            try
            {
                if (!GetActivePrinter(document).Contains(printer))
                {
                    try
                    {
                        document.Application.ActivePrinter = printer;
                        docPrinterChanged = true;                            
                    }
                    catch (Exception)
                    {
                        try
                        {
                            app.ActivePrinter = printer;
                            appPrinterChanged = true;
                        }
                        catch (Exception)
                        {
                            continue;
                        }
                    }
                }
                object oMissing = System.Reflection.Missing.Value;
                document.PrintOut(
                   true,            // Background
                   false,           // Append overwrite
                   oMissing,        // Page Range
                   oMissing,        // Print To File - OutputFileName
                   oMissing,        // From page
                   oMissing,        // To page
                   oMissing,        // Item
                   numberOfCopies,  // Number of copies to be printed
                   oMissing,        //
                   oMissing,        //
                   PrintToFile,     // Print To file
                   true             // Collate
                   );
                break;
            }
            catch (Exception)
            {
                continue;
            }
        }
        try
        {
            if(docPrinterChanged)
                document.Application.ActivePrinter = oldPrinterName;
            else if(appPrinterChanged)
                app.ActivePrinter = oldPrinterName;   
        }
        catch (Exception)
        {
        }
    }

    private static string GetActivePrinter(dynamic document)
    {

        string activePrinter = document.Application.ActivePrinter;

        if (activePrinter.Length >= 0)
            return activePrinter;
        return null;
    }

当使用MS Excel的上述功能我更新,如下所示的打印机名称。 尽管从MS Excel实例传递打印机名称以上述功能,我使用

    bool IFilePrint.PrintFile(string fullFileName, string printerName, int numberOfCopies)
    {

        // .......

        Excel.Workbook document = null;
        try
        {
            document = this.Application.Workbooks.Open(fullFileName);
        }
        catch
        {
            document = null;
        }

        string portNumber = null;

        // Find correct printerport
        using (RegistryKey key = Registry.CurrentUser.OpenSubKey(fullFileName))
        {
            if (key != null)
            {
                object value = key.GetValue(printerName);
                if (value != null)
                {
                    string[] values = value.ToString().Split(',');
                    if (values.Length >= 2) port = values[1];
                }
            }
        }

        // Get current concatenation string ('on' in en, 'auf' in de, etc..)
        var split = this.Application.ActivePrinter.Split(' ');
        if (split.Length >= 3)
            printerName = String.Format("{0} {1} {2}", printerName, split[split.Length - 2], port);

        PrintToPrinter(this.Application, document, printerName, numberOfCopies);

        // ...........
        }
        catch (Exception)
        { }
        result = true;   
        return result;
    }

这个进一步的检查可以做到:

1)检查是否存在预期的打印机使用PrinterSettings类。

2)(打印到文件)检查是否打算打印选项是PDF / XPS到/传真等。



文章来源: COMException when assigning to Excel.Application.ActivePrinter