Set custom document properties with Word interop

我只是一个虾纸丫 提交于 2019-12-28 18:05:25

问题


I want to set some custom document properties of a word document I'm creating in my C# code. To do this, I followed this MSDN article and came up with this code:

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

Unfortunately, I get this error whenever it reaches the code:

HRESULT: 0x80004002 (E_NOINTERFACE)

Why is that? I used the interfaces exactly as described my MSDN, why doesn't it work?

I'm using Interop for office 2010 and .net 3.5


回答1:


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



回答2:


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



回答3:


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


来源:https://stackoverflow.com/questions/12690409/set-custom-document-properties-with-word-interop

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