gpt4 book ai didi

.net - 分配给 Excel.Application.ActivePrinter 时出现 COMException

转载 作者:行者123 更新时间:2023-12-04 22:08:42 24 4
gpt4 key购买 nike

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

但是,当我尝试分配给应用程序的 ActivePrinter 属性时,会抛出带有以下消息的 COMException:

Exception from 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\Microsoft\Windows NT\CurrentVersion\Devices



或者

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Devices



使用链接中详述的方法,或者在我的情况下使用 Microsoft.Win32.Registry.GetValue()。后者将返回类似于“winspool,Ne01:”的内容。
以“Fax on Ne01:”的方式将该字符串的最后一部分连接到打印机名称上,可以毫无异常(exception)地设置 ActivePrinter 属性。

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

最佳答案

我在使用 excel interop 打印 excel 文档时遇到了同样的异常。

使用 MS Word:-

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

但是使用 MS Excel :-
document.Application.ActivePrinter = "Brother MFC.. Printer"; // throws COM exception

以下是使用 office interop 打印任何 office(MS Word、MS Excel、PS Powerpoint)文档的通用功能。
    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) (打印到文件)检查预期的打印选项是否是 To PDF/To XPS/FAX 等。

关于.net - 分配给 Excel.Application.ActivePrinter 时出现 COMException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14864189/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com