2013-02-13 116 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到/傳真等