Customize document properties using Word interop

I want to set some custom document properties in a text document that I create 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 when it reaches the code:

HRESULT: 0x80004002 (E_NOINTERFACE)

Why? I used the interfaces just like my MSDN described, why doesn't it work?

I use Interop for Office 2010 and .net 3.5

+6
source share
3 answers

After you asked a question in the MSDN forums , the answer was raised. The problem is that the way I tried was specific to VSTO. Due to my ignorance, I confused VSTO, Interop, and other definitions, thereby interfering with this issue incorrectly.

Now it 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); 
+4
source

You need to use CustomDocumentProperties , not BuiltInDocumentProperties . See the MSDN link for using custom document properties in Word (and the 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(); 
+5
source

SliverNinja answer above is correct. I forgot that you should have added to the collection until I ported the old VB code. I had to set and read a bunch of doc properties, so here are a few extension methods for reading / writing from either inline documents or from CustomDocumentProperties in Word. This is NetOffice code, but you can convert it to VSTO just by changing the operators used.

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

Source: https://habr.com/ru/post/926753/


All Articles