如何阅读'扩展'没有Office.Interop的MS Word文件标签?

时间:2016-02-15 11:56:19

标签: c# file ms-word office-interop file-properties

我有.docx个文件,其中包含仅为MS Office文件指定的自定义属性。 File properties

如果我尝试在未安装MS office的计算机中打开同一文件,则文件详细信息选项卡中没有Tags属性。

我需要在我的c#代码中阅读Tags

我尝试了this solution并将Tags索引称为18。然后我使用下一个代码:

public class TagsReader : ITagsReader
{
    private const int keywordsIndex = 18;

    public string Read(string filePath)
    {
        var fullPath = Path.GetFullPath(filePath);

        var directoryName = Path.GetDirectoryName(fullPath);
        Folder dir = GetShell32Folder(directoryName);
        var fileName = Path.GetFileName(fullPath);

        FolderItem item = dir.ParseName(fileName);
        return dir.GetDetailsOf(item, keywordsIndex);
    }

    private Folder GetShell32Folder(string folderPath)
    {
        var shellAppType = Type.GetTypeFromProgID("Shell.Application");
        var shell = Activator.CreateInstance(shellAppType);
        return (Folder)shellAppType.InvokeMember("NameSpace",
        BindingFlags.InvokeMethod, null, shell, new object[] { folderPath });
    }
}

但是对于没有安装MS Office的计算机它不起作用。它仅适用于.doc个文件,但不适用于.docx。现在我使用了基于Inerop的解决方案,该解决方案不稳定,资源密集且需要将MS Office安装到服务器:

public class WordTagsReader : ITagsReader
{
    private readonly string[] availableFileExtensions = { ".docx" };
    public string Read(string filePath)
    {
        var fileExtension = Path.GetExtension(filePath);
        if (!availableFileExtensions.Contains(fileExtension))
            return null;

        dynamic application = null;
        dynamic document = null;
        var tags = string.Empty;
        try
        {
            var typeWord = Type.GetTypeFromProgID("Word.Application");
            application = Activator.CreateInstance(typeWord);
            application.Visible = false;
            application.DisplayAlerts = false;
            var fullFilePath = Path.GetFullPath(filePath);
            document = application.Documents.Open(fullFilePath);
            tags = document.BuiltInDocumentProperties["Keywords"].Value;
        }
        finally
        {
            if (document != null)
            {
                document.Close();
                document = null;
            }
            if (application != null)
            {
                application.Quit();
                application = null;
            }
        }

        return tags;
    }
}

此代码可能会不时崩溃并留下运行资源和阻止文件的MS Word实例。我和许多处理人员在同一时间工作,然后我就无法分开"离开"来自正常工作和清洁资源的实例。

这是搜索备用解决方案的原因。有没有办法在不使用Tags的情况下阅读Office.Interop等特定(自定义)属性?

3 个答案:

答案 0 :(得分:3)

U可以使用暖灯.docx格式读取。像这样:

using System.IO.Packaging;

var package = Package.Open(ms, FileMode.Open, FileAccess.ReadWrite);
var corePart = package.GetPart(new Uri("/docProps/core.xml", UriKind.Relative))
XDocument settings;
using (TextReader tr = new StreamReader(settingsPart.GetStream()))
    settings = XDocument.Load(tr);

XNamespace cp = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
var tags = settings.Root.Element(cp + "keywords");

无需使用其他库或sdk。只有System.IO,只有铁杆!

答案 1 :(得分:2)

我建议使用Open Xml Sdk,打开xml是新的'办公室标准。使用此代码可以读取标记:(注意您需要使用DocumentFormat.OpenXml.Packaging命名空间)

string tags = "";
using(var doc = WordProcessingDocument.Open("filename",false)
    tags = doc.PackageProperties.KeyWords;

使用open xml并不需要在机器上安装任何与办公室相关的东西,因此它非常适合在服务器上或在您的示例中用于在没有办公室的机器上阅读/编辑文档安装。

答案 2 :(得分:2)

Microsoft目前不建议也不支持从任何无人参与的非交互式客户端应用程序或组件(包括ASP,ASP.NET,DCOM和NT服务)自动化Microsoft Office应用程序,因为Office在此环境中运行Office时,可能会出现不稳定的行为和/或死锁。

如果要构建在服务器端上下文中运行的解决方案,则应尝试使用已为安全无人值守执行的组件。或者,您应该尝试找到允许至少部分代码在客户端运行的替代方法。如果从服务器端解决方案使用Office应用程序,则应用程序将缺少许多成功运行的必要功能。此外,您将承担整体解决方案稳定性的风险。请在Considerations for server-side Automation of Office文章中详细了解相关内容。

作为一种解决方法,您可以使用Open XML SDK,有关详细信息,请参阅Welcome to the Open XML SDK 2.5 for Office。或者使用为服务器端执行而设计的任何第三方组件。例如,看看Aspose。