4

更新:这是 Silverlight 4 beta 中已确认的错误。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,当谷歌搜索时,它什么也没有。

4

2 回答 2

6

这当然不是 C# 问题——VB.NET 也有同样的问题。这里要么存在错误,要么存在未记录的内容,但在任何一种情况下,似乎都无法声明集合对象。

然而,还有另一种方法,它是访问集合的各个成员。这是一个示例(在 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
于 2010-01-01T16:50:08.923 回答
1

可能与 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<dynamic>().Select(x=>(string)x.Result.Text).ToArray()));

//Method 2
foreach (dynamic fld in fields)
 Console.WriteLine(fld.Result.Text);
于 2010-01-06T18:18:30.387 回答