我正在开发文字自动化应用程序,我面临着意外的RPC / COM投射异常的严重问题
[System.InvalidCastException:Nie możnarzutowaćobiektumodelu COM typu 'System .__ ComObject'na typ interfejsu 'Microsoft.Office.Interop.Word._Application'。 Ta operacjaniepowiodłasię,ponieważ wywołaniemetodyQueryInterface dla składnikamodeluCOM w celu uzyskania interfejsu o identyfikatorze IID '{00020970-0000-0000-C000-000000000046}' niepowiodłosięzpowodu następującegabłędu:Serwer RPC开玩笑 niedostępny。 (WyjątekodHRESULT: 0x800706BA)。]
从波兰语到英语的翻译:
无法将System .__ ComObject强制转换为 Microsoft.Office.Interop.Word._Application。 原因是QueryInterface为 IID '{00020970-0000-0000-C000-000000000046}' 失败 - RPC服务器不可用 - 错误代码HRESULT:0x800706BA
这里是wordapp模块的简介:
初始化 - 用户登录后。
using Microsoft.Office.Interop.Word;
public class WordApp
{
Application app = null;
object m = System.Reflection.Missing.Value;
object oFalse = false;
object oTrue = true;
...
app = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application.12")) as Application;
app.Visible = false;
app.DisplayAlerts = WdAlertLevel.wdAlertsNone;
app.PrintPreview = false;
我正在使用Activator.CreateInstance而不是app = new Application() - 这里是explanation。
然后用户可以在wordapp模块中执行2个动作
a)打印准备好的docx文件
System.Windows.Forms.PrintDialog pd = new System.Windows.Forms.PrintDialog();
...
this.app.ActivePrinter = pd.PrinterSettings.PrinterName;
object oNumcopies = pd.PrinterSettings.Copies;
object oRange = WdPrintOutRange.wdPrintAllDocument;
object inputname = fullPath;
Document doc = app.Documents.Add(
ref inputname,
ref m,
ref m,
ref m);
try
{
// Print the document
doc.PrintOut(ref oFalse, ref oFalse, ref oRange,
ref m, ref m, ref m,
ref m, ref oNumcopies, ref m, ref m,
ref oFalse, ref m, ref m,
ref m, ref m, ref m, ref m,
ref m);
}
finally
{
doc.Close(ref oFalse, ref m, ref m);
doc = null;
}
b)将docx转换为mht
object inputname = docxname;
object outputname = htmlname;
object fileType = WdSaveFormat.wdFormatWebArchive;
Document doc = app.Documents.Add(
ref inputname,
ref m,
ref m,
ref m);
try
{
doc.SaveAs(ref outputname, ref fileType,
ref m, ref m, ref m, ref m, ref m, ref m, ref m,
ref m, ref m, ref m, ref m, ref m, ref m, ref m);
}
finally
{
doc.Close(ref oFalse, ref m, ref m);
doc = null;
}
当用户注销时,我发布了单词实例:
object oSaveChanges = WdSaveOptions.wdDoNotSaveChanges;
app.Quit(
ref oSaveChanges,
ref m,
ref m);
异常会在随机位置抛出 - 但最常见的地方是app.Documents.Add附近。在那个例外之后,app.Quit是不可能的。似乎单词实例已经死了。
我在eventlog(应用程序范围)中找到了这个东西:
EventType offdiag12,P1 585d8a02-f370-4c04-85b6-fccad7e80459255ec053-6dbd-4a22-9e59-112a79de8c6a, P2 NIL,P3 NIL,P4 NIL,P5 NIL,P6 NIL,P7 NIL,P8 NIL,P9 NIL,P10 NIL。
我运行办公室诊断,但没有发现任何错误。
是否可以从系统中启用/查找更多错误信息?
此代码在我的开发机器(vista)上运行得非常好。问题出现在客户机器上(通常是winxp sp2 / sp3)。
我的代码中有错误或什么?
我需要添加的唯一一件事。 WordModule初始化/关闭/打印函数从主线程调用,并从后台工作程序的线程中保存。
答案 0 :(得分:4)
您所描述的内容通常指的是以下情况。您使用COM out-proc服务器(在单独的进程中实例化的COM对象,而不是在与程序相同的进程中),并且由于某种原因,COM服务器遇到致命错误并意外终止。您使用的COM对象不再存在。由于RPC用于与out-proc COM服务器交互,并且服务器端在终止后不再存在,因此您收到错误消息,指出RPC服务器不可用,这是真的,但看起来很混乱。
您必须研究并消除COM服务器终止的原因。最可能的原因如下:
答案 1 :(得分:1)
我不知道,但这里有一些基于一般经验的建议。您可以尝试使用不同的m
而不是在所有参数之间共享一个(这个想法是,如果值被内部混乱,则可能会产生不可预测的结果)。您也可以尝试在任何地方尝试提供合理的值(而不是m
)。某些版本的API可能比其他版本更宽容。