2016-02-15 56 views
1

我有.docx文件,其中只为MS Office文件指定了自定义属性。 File properties如何在没有Office.Interop的情况下阅读'Extended'MS Word文件标签?

如果我试图打开电脑相同的文件没有安装MS办公室再有就是在文件的详细信息标签不标签属性。

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

我试过this solution和retieve 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 }); 
    } 
} 

但它并不适用于电脑没有安装微软Office工作。它仅适用于.doc文件,但不适用于.docx。现在我用Inerop基础的解决方案是不是稳定的,资源密集型的,需要安装微软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

+0

TY到所有的答案。 –

回答

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,只有硬核!

+0

甚至有必要获得零件(我不知道肯定)? var tags = package.PackageProperties.Keywords; –

2

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

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

使用的Open XML并不需要与安装在机器所以它非常适合于使用它的任何办公室服务器或在您的示例中读取/编辑没有安装Office的计算机上的文档。

+0

我会尽快测试您的解决方案,TY。 –

+0

谢谢你的问题。首先我很惊讶,我[需要添加WindowsBase.dll](http://stackoverflow.com/questions/10427041/references-needed-to-use-open-xml-from-within-net-web-application)到使用OpenXml SDK。 另外,对于使用Interop正确打开的文件,我得到了'FileFormatException'(_“文件包含损坏的数据。”_)。我无法更改文件格式,因为它是我们客户输入的文档流。我可以将Open XML与MS Word中创建的文件一起使用并保存为.docx文件吗? –

+0

打开xml仅适用于docx文件,将doc转换为docx(afaik)的唯一方法是打开它并用word保存它:/如果您正在处理旧文档,那么您唯一的解决方案将是互操作性,我很害怕。 –

1

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

如果您正在构建一个在服务器端上下文中运行的解决方案,那么您应该尝试使用对于无人执行安全的组件。或者,您应该尝试找到允许至少部分代码运行客户端的替代方案。如果您从服务器端解决方案使用Office应用程序,则该应用程序将缺少成功运行所需的许多必要功能。此外,您将面临整体解决方案稳定性的风险。请阅读Considerations for server-side Automation of Office文章中的更多内容。

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

相关问题