6

我想设置我在 C# 代码中创建的 word 文档的一些自定义文档属性。为此,我按照这篇 MSDN 文章提出了以下代码:

using Word = Microsoft.Office.Interop.Word; // Version 12.0.0.0
word = new Word.Application();
word.Visible = false;
Word._Document doc = word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
logger.Info("Setting document properties");
Core.DocumentProperties properties = (Core.DocumentProperties)doc.BuiltInDocumentProperties;
properties["Codice_documento"].Value = args[3];
properties["Versione_documento"].Value = args[4];

不幸的是,每当它到达代码时,我都会收到此错误:

HRESULT:0x80004002(E_NOINTERFACE)

这是为什么?我完全按照我的 MSDN 中描述的方式使用了接口,为什么它不起作用?

我正在为 Office 2010 和 .net 3.5 使用 Interop

4

4 回答 4

5

你需要使用CustomDocumentProperties,而不是BuiltInDocumentProperties。请参阅有关在 Word 中使用自定义文档属性的 MSDN 参考以及此处的 MSDN 视频)。您还需要检查属性是否存在并在尝试分配其值之前创建它。

Core.DocumentProperties properties = (Core.DocumentProperties)this.Application.ActiveDocument.CustomDocumentProperties;
if (properties.Cast<DocumentProperty>().Where(c => c.Name == "DocumentID").Count() == 0)
  properties.Add("DocumentID", false, MsoDocProperties.msoPropertyTypeString, Guid.NewGuid().ToString());
var docID = properties["DocumentID"].Value.ToString();
于 2012-10-02T13:03:40.987 回答
5

在MSDN 论坛上提问后,答案就出来了。问题是,我尝试的方式是特定于 VSTO 的。由于我不知道,我混淆了 VSTO、Interop 和其他定义,从而错误地标记了这个问题。

它现在使用以下代码工作:

logger.Info("Setting document properties");
object properties = doc.CustomDocumentProperties;
Type propertiesType = properties.GetType();

object[] documentCodeProperty = { "Codice_documento", false, Core.MsoDocProperties.msoPropertyTypeString, args[3] };
object[] documentVersionPoperty = { "Versione_documento", false, Core.MsoDocProperties.msoPropertyTypeString, args[4] };

propertiesType.InvokeMember("Add", BindingFlags.InvokeMethod, null, properties, documentCodeProperty);
propertiesType.InvokeMember("Add", BindingFlags.InvokeMethod, null, properties, documentVersionPoperty);
于 2012-10-09T07:52:05.640 回答
0

SliverNinja 上面的回答是正确的。在我移植了一些旧的 VB 代码之前,我忘记了你必须添加到集合中。我必须设置和读取一堆文档属性,所以这里有几个扩展方法可以从 Word 中的 BuiltInDocumentProperties 或 CustomDocumentProperties 读取/写入。这是 NetOffice 代码,但您可以通过更改 using 语句将其转换为 VSTO。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetOffice.OfficeApi;
using NetOffice.OfficeApi.Enums;
using NetOffice.WordApi;

namespace PalabraAddin {
    public static class ExtDocument {

        public static T GetCustomProperty<T>(this Document doc, string name, T defaultValue) {
            return doc.GetProperty(doc.CustomDocumentProperties, name, defaultValue);
        }

        public static T GetBuiltInProperty<T>(this Document doc, string name, T defaultValue) {
            return doc.GetProperty(doc.BuiltInDocumentProperties, name, defaultValue);
        }

        public static T SetCustomProperty<T>(this Document doc, string name, T value) {
            return doc.SetProperty(doc.CustomDocumentProperties, name, value);
        }

        public static T SetBuiltInProperty<T>(this Document doc, string name, T value) {
            return doc.SetProperty(doc.BuiltInDocumentProperties, name, value);
        }

        public static T GetProperty<T>(this Document doc, object collection, string name, T defaultValue) {
            var properties = (DocumentProperties) collection;
            foreach (var prop in properties.Where(prop => prop.Name == name))
                return (T) prop.Value;
            return defaultValue;
        }

        public static T SetProperty<T>(this Document doc, object collection, string name, T value) {
            var properties = (DocumentProperties) collection;
            foreach (var prop in properties.Where(prop => prop.Name == name)) {
                if (!((T) prop.Value).Equals(value))
                    prop.Value = value;
                return value;
            }

            MsoDocProperties propType;
            if (value is Boolean) 
                propType = MsoDocProperties.msoPropertyTypeBoolean;
            else if (value is DateTime)
                propType = MsoDocProperties.msoPropertyTypeDate;
            else if (value is double || value is Single)
                propType = MsoDocProperties.msoPropertyTypeFloat;
            else if (value is int)
                propType = MsoDocProperties.msoPropertyTypeNumber;
            else 
                propType = MsoDocProperties.msoPropertyTypeString;

            properties.Add(name, false, propType, value);
            return value;
        }
    }
}
于 2014-03-08T21:42:50.457 回答
0

我用这个简单的代码解决了它:

foreach (var property in _WordDoc.CustomDocumentProperties)
{
   if(property.Name == target)
      property.Value = value;
}
于 2020-02-26T13:16:26.920 回答