Set custom document properties with Word interop

亡梦爱人 提交于 2019-11-28 11:26:55

You need to use CustomDocumentProperties, not BuiltInDocumentProperties. See MSDN reference on using Custom Document Properties in Word (and MSDN video here). You also need to check if the property exists and create it before trying to assign its value.

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

After asking the question in the MSDN forums, the answer was brought up. The problem is, that the way I tried was specific to VSTO. Due to my unknowing, I mixed up VSTO, Interop and other definitions, thus tagging this question wrong.

It now works using the following code:

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

SliverNinja's answer above is correct. I forgot you had to .Add to the collection until I ported some old VB code. I had to set and read a bunch of doc properties, so here are a couple extension methods to read/write from either the BuiltInDocumentProperties or the CustomDocumentProperties in Word. This is NetOffice code, but you can convert it to VSTO by just changing the using statements.

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;
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!