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

使用Word interop设置自定义文档属性,interop,ms-word,vsto,office-2010,office-addins,Interop,Ms Word,Vsto,Office 2010,Office Addins,我想为我在C#代码中创建的word文档设置一些自定义文档属性。为此,我遵循并提出了以下代码: 使用Word=Microsoft.Office.Interop.Word;//版本12.0.0.0 word=新单词。应用程序(); 可见字=假; Word.\u Document doc=Word.Documents.Add(ref缺失、ref缺失、ref缺失、ref缺失); logger.Info(“设置文档属性”); Core.DocumentProperties属性=(Core.Document

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

使用Word=Microsoft.Office.Interop.Word;//版本12.0.0.0
word=新单词。应用程序();
可见字=假;
Word.\u Document doc=Word.Documents.Add(ref缺失、ref缺失、ref缺失、ref缺失);
logger.Info(“设置文档属性”);
Core.DocumentProperties属性=(Core.DocumentProperties)doc.BuiltInDocumentProperties;
属性[“Codice_documento”]。值=args[3];
属性[“Versione_documento”]。值=args[4];
不幸的是,每当它到达代码时,我都会遇到这个错误:

HRESULT:0x80004002(电子接口)

为什么呢?我使用的接口与我的MSDN描述的完全一样,为什么它不工作

我正在使用office 2010和.net 3.5的互操作,您需要使用,而不是。见(和)。您还需要检查属性是否存在,并在尝试分配其值之前创建它

Core.DocumentProperties=(Core.DocumentProperties)this.Application.ActiveDocument.CustomDocumentProperties;
if(properties.Cast().Where(c=>c.Name==“DocumentID”).Count()==0)
Add(“DocumentID”,false,MsoDocProperties.msoPropertyTypeString,Guid.NewGuid().ToString());
var docID=properties[“DocumentID”].Value.ToString();

在中提出问题后,给出了答案。问题是,我尝试的方式是针对VSTO的。由于我不知道,我混淆了VSTO、Interop和其他定义,因此将这个问题标记为错误

它现在使用以下代码工作:

logger.Info(“设置文档属性”);
对象属性=doc.CustomDocumentProperties;
类型propertiesType=properties.GetType();
对象[]documentCodeProperty={“Codice_documento”,false,Core.MsoDocProperties.msopPropertyTypeString,args[3]};
对象[]documentVersionPoperty={“Versione_documento”,false,Core.MsoDocProperties.msopPropertyTypeString,args[4]};
propertiesType.InvokeMember(“添加”,BindingFlags.InvokeMethod,null,properties,documentCodeProperty);
propertiesType.InvokeMember(“添加”,BindingFlags.InvokeMethod,null,properties,documentVersionPoperty);

Sliveninja上面的回答是正确的。我忘了你必须添加到集合中,直到我移植了一些旧的VB代码。我必须设置和读取一组文档属性,因此这里有几个扩展方法可以从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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用NetOffice.OfficeApi;
使用NetOffice.OfficeApi.Enums;
使用NetOffice.WordApi;
帕拉布拉丁{
公共静态类ExtDocument{
公共静态T GetCustomProperty(此文档文档,字符串名称,T defaultValue){
返回doc.GetProperty(doc.CustomDocumentProperties、名称、默认值);
}
公共静态T GetBuiltInProperty(此文档文档,字符串名称,T defaultValue){
返回doc.GetProperty(doc.BuiltInDocumentProperties,name,defaultValue);
}
公共静态T SetCustomProperty(此文档文档,字符串名称,T值){
返回doc.SetProperty(doc.CustomDocumentProperties、名称、值);
}
公共静态T SetBuiltInProperty(此文档文档,字符串名称,T值){
返回doc.SetProperty(doc.BuiltInDocumentProperties、名称、值);
}
公共静态T GetProperty(此文档文档、对象集合、字符串名称、T defaultValue){
var属性=(DocumentProperties)集合;
foreach(properties.Where中的var prop(prop=>prop.Name==Name))
返回(T)属性值;
返回默认值;
}
公共静态T SetProperty(此文档文档、对象集合、字符串名称、T值){
var属性=(DocumentProperties)集合;
foreach(properties.Where中的var prop(prop=>prop.Name==Name)){
如果(!((T)属性值)。等于(值))
道具价值=价值;
返回值;
}
MsoDocProperties propType;
if(值为布尔值)
propType=MsoDocProperties.msopPropertyTypeBoolean;
else if(值为DateTime)
propType=MsoDocProperties.msopPropertyTypeDate;
else if(值为双精度| |值为单精度)
propType=MsoDocProperties.msopPropertyTypeFloat;
else if(值为int)
propType=MsoDocProperties.msopPropertyTypeNumber;
其他的
propType=MsoDocProperties.msopPropertyTypeString;
添加(名称、false、propType、值);
返回值;
}
}
}

我用这个简单的代码解决了这个问题:

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

当它到达哪个代码?什么是
args
在第3行之前没有提到它?我在第3行中转换属性。参数是传递给程序的字符串参数。它们肯定是用值填充的,我会事先检查。用哪个值填充?
args[3]
args[4]
的类型是什么?似乎他们没有实现target
DocumentProperty
所期望的接口,问题不在于参数。错误在第2行中抛出。但是当您更新属性并在Word文档文本中引用它时,它不会自动更新,对吗?我必须点击它并按F9更新它。有人知道通过编程实现这一点的方法吗?我不能使用
this.Application.ActiveDocument
,因为我是动态创建文档的。我有一个
\u Document
的实例,但即使在使用
CustomDocumentProperty时