使用Word interop设置自定义文档属性

时间:2012-10-02 12:38:42

标签: interop ms-word vsto office-2010 office-addins

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

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描述使用接口,为什么它不起作用?

我正在使用Interop for office 2010和.net 3.5

4 个答案:

答案 0 :(得分:5)

您需要使用CustomDocumentProperties,而不是BuiltInDocumentProperties。请参阅MSDN reference on using Custom Document Properties in WordMSDN video here )。您还需要检查属性是否存在并在尝试分配其值之前创建它。

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();

答案 1 :(得分:4)

MSDN forums中提问之后,提出了答案。问题是,我尝试的方式特定于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);

答案 2 :(得分:0)

SliverNinja上面的回答是正确的。我忘了你必须。添加到集合,直到我移植了一些旧的VB代码。我必须设置和读取一堆doc属性,所以这里有一些扩展方法可以从BuildInDocumentProperties或Word中的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;
        }
    }
}

答案 3 :(得分:0)

我使用以下简单代码解决了该问题:

foreach (var property in _WordDoc.CustomDocumentProperties)
{
   if(property.Name == target)
      property.Value = value;
}