使用Silverlight 4中的ComAutomationFactory迭代Word文档字段

更新 :这是Silverlight 4测试版中确认的错误。 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=523052

我通过切换到完整的WPF应用程序并使用常规的旧Microsoft.Office.Interop.Word解决了这个问题。 但我仍然对使用ComAutomationFactory的动态值如何使其工作非常感兴趣。

这可能更像是一个C#4.0问题,但我想要做的是利用受信任的SL4应用程序中的ComAutomationFactory类来加载Word文档,更改一些文本并打印它。

使用常规的Windows应用程序,非常简单:

Object oMissing = System.Reflection.Missing.Value; Object oTrue = true; Object oFalse = false; Application oWord = new Application(); Document oWordDoc = new Document(); oWord.Visible = false; object oTemplatePath = "C:\\Users\\jwest\\Desktop\\DocumentTemplate.dotx"; oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); foreach (Field myMergeField in oWordDoc.Fields) 

但是,在SL4中,您必须使用dynamic关键字。 它工作正常,直到我尝试迭代我的字段:

  Object oMissing = System.Reflection.Missing.Value; Object oTrue = true; Object oFalse = false; dynamic oWord = ComAutomationFactory.CreateObject("Word.Application"); oWord.Visible = false; object oTemplatePath = "C:\\Users\\jwest\\Desktop\\DocumentTemplate.dotx"; dynamic oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); dynamic fields = oWordDoc.Fields; foreach (var myMergeField in fields) 

在这种情况下,我得到一个运行时错误,说我无法将ComAutomationMetaObjectProvider隐式转换为IEnumerable。 无论我做什么,与我的Word com对象相关的任何属性都是ComAutomationMetaObjectProvider类型,我不能迭代它们。

有人提到我应该尝试从成员中将字段作为字符串。

  for (int i = 0; i < oWordDoc.Fields.Count; i++) { String field = oWordDoc.Fields.Item[i].Result.Text; } 

这导致一个有趣的例外:HRESULT:0x800A16E6,当用Google搜索时,它绝对没有任何结果。

它肯定不是C#问题 – VB.NET也有同样的问题。 这里有一个bug或者没有记录的东西,但在任何一种情况下,似乎都不可能声明集合对象。

还有另一种方法,它是访问集合的各个成员。 这是一个示例(在VB.NET中),允许您通过Fields.Item进行迭代。 (这里没有错误检查或关闭Word;我的.dotx有两个字段 – 1)日期和2)作者)。

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click Dim wrd As Object = ComAutomationFactory.CreateObject("Word.Application") Dim path As String = "C:\Users\me\test.dotx" Dim wordDoc As Object = wrd.Documents.Add(path) Dim fieldsCount As Integer = wordDoc.Fields.Count Dim fieldResults As String = Nothing For i As Integer = 1 To fieldsCount fieldResults = fieldResults & " " & wordDoc.Fields.Item(i).Result.Text & vbNewLine Next TextBox1.Text = "Field Results: " & fieldResults End Sub 

可能与Silverlight 4.0的ComAutomationFactory实现有关。 我没有VS2K10 Beta 2所以无法检查。

使用“动态”类型在控制台应用程序中运行良好,但…

 dynamic oWord = //ComAutomationFactory.CreateObject("Word.Application"); Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application", true)); oWord.Visible = false; object oTemplatePath = "c:\\vishal.dotx"; dynamic oWordDoc = oWord.Documents.Add(ref oTemplatePath); dynamic fields = oWordDoc.Fields; Console.WriteLine("template has {0} merge flds", fields.Count); //Method 1 Console.WriteLine(string.Join("\n", ((IEnumerable)oWordDoc.Fields).Cast().Select(x=>(string)x.Result.Text).ToArray())); //Method 2 foreach (dynamic fld in fields) Console.WriteLine(fld.Result.Text);