2013-02-13 117 views
1

我有一个函数,其中传递了一个Microsoft.Office.Interop.Excel.Application实例。该功能使用Windows内置的传真打印机或Microsoft XPS Document Writer将文件保存为tiff图像。当分配给Excel.Application.ActivePrinter时发生COMException

然而,当我试图给应用程序的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相关的无知,但是当搜索google/stackoverflow时,几乎找不到与此有关的任何内容,除了一两个旧的,未答复的线程。有一些是涉及到大量数据/大范围的,但不是ActivePrinter属性

编辑 - 答案的简要总结,以M Patel的链接详细说明:

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

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

HKEY_LOCAL_MACHINE \ SOFTWARE \微软\ Windows NT \ CurrentVersion \ Devices

使用链接中详述的方法,o r在我的情况下使用Microsoft.Win32.Registry.GetValue()。后者将按照“winspool,Ne01:”的顺序返回。 以“传真Ne01:”的方式将该字符串的最后部分连接到打印机名称上,允许设置ActivePrinter属性而没有异常。

我也应该注意到,我的问题是在2010年的Excel

+0

问题依然存在在Excel 2013以及级联字符串转换与Excel中的用户语言。我已经将我的解决方案添加到http://stackoverflow.com/questions/29921150/c-sharp-setting-a-printer/32862651#32862651 – 2015-09-30 09:36:15

回答

1
+1

这就是票,完美运作!想一想,我一直在围绕注册表的确切部分,但出于与此问题完全无关的原因!非常感谢。 – dbr 2013-02-14 09:10:07

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 

下面是用来打印任何Office(微软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到/传真等