2

我的.docx文件具有仅为 MS Office 文件指定的自定义属性。 文件属性

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

我需要阅读Tags我的 c# 代码。

我尝试了这个解决方案并将索引检索Tags18. 然后我使用了下一个代码:

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 实例,该实例占用资源并阻止文件。我有许多处理程序同时工作,然后我无法将“左”实例与正常工作和清洁的资源分开。

这就是寻找替代解决方案的原因。有没有办法在Tags不使用的情况下读取特定(自定义)属性Office.Interop

4

3 回答 3

4

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

于 2016-02-15T12:26:28.450 回答
2

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

如果您正在构建在服务器端上下文中运行的解决方案,您应该尝试使用已确保无人值守执行安全的组件。或者,您应该尝试找到允许至少部分代码在客户端运行的替代方案。如果您使用来自服务器端解决方案的 Office 应用程序,该应用程序将缺少许多成功运行所需的功能。此外,您将承担整体解决方案稳定性的风险。在Office 服务器端自动化的注意事项文章中阅读有关此内容的更多信息。

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

于 2016-02-15T12:45:32.680 回答
2

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

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

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

于 2016-02-15T12:07:39.427 回答