c# - 如何在没有 Office.Interop 的情况下读取 'Extended' MS Word 文件标签?

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

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

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

我需要在我的 C# 代码中读取 标签

我试过了 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。现在我使用了基于 Interop 的解决方案,它不稳定,资源密集,需要在服务器上安装 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 运行实例占用资源和 block 文件。我有许多处理程序同时工作,然后我无法将“左”实例与正常工作和清洁的资源分开。

这就是搜索替代解决方案的原因。有没有一种方法可以在不使用 Office.Interop 的情况下读取特定(自定义)属性,例如 Tags

最佳答案

您可以使用暖灯.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,只有铁杆!

关于c# - 如何在没有 Office.Interop 的情况下读取 'Extended' MS Word 文件标签?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35408761/

相关文章:

c# - 边框内的按钮

file - 如何在Flutter中获取文件扩展名?

java - 如何使用 Aspose Word for Java 从 .doc 读取文本和字体

vba - 如何将宏添加到 Word 2010 或 PowerPoint 2010 图表?

c# - Word Interop 复制表格单元格的格式化文本

c# - 为什么退出编辑模式时我的 datagridview 行会被排序?

c# - 如何创建模块化 Blazor Web 应用

c# - 如何使用 Facebook(或其他 ID)登录我的 asp.net 应用程序?

ruby - 使用 Ruby 文件设置内容类型创建的文件?

macos - 图像缓存的平面或嵌套目录结构?