我想在我的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
答案 0 :(得分:5)
您需要使用CustomDocumentProperties
,而不是BuiltInDocumentProperties
。请参阅MSDN reference on using Custom Document Properties in Word(和MSDN 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;
}