C# 如何阅读';扩展的';没有Office.Interop的MS Word文件标记?
我有一个C# 如何阅读';扩展的';没有Office.Interop的MS Word文件标记?,c#,file,ms-word,office-interop,file-properties,C#,File,Ms Word,Office Interop,File Properties,我有一个.docx文件,其中仅为MS Office文件指定了自定义属性。 若我试图在未安装MS office的计算机中打开同一文件,则“文件详细信息”选项卡中并没有“标记”属性 我需要阅读c#code中的标记 我试图检索标签索引为18。然后我使用了下一个代码: public class TagsReader : ITagsReader { private const int keywordsIndex = 18; public string Read(string fileP
.docx
文件,其中仅为MS Office文件指定了自定义属性。
若我试图在未安装MS office的计算机中打开同一文件,则“文件详细信息”选项卡中并没有“标记”属性
我需要阅读c#code中的标记
我试图检索标签
索引为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的实例,这些实例占用资源并阻塞文件。我有许多处理程序同时工作,因此我无法将“左”实例与正常工作和干净的资源分开
这就是搜索替代解决方案的原因。是否有一种方法可以在不使用Office.Interop的情况下读取特定(自定义)属性,如标记?我建议使用,因为开放式xml是Office的“新”标准。使用此代码可以读取标记:(注意,您需要为此使用DocumentFormat.OpenXml.Packaging
命名空间)
使用open xml不需要在计算机上安装任何与office相关的内容,因此它非常适合在服务器上使用,或者在您的示例中,用于在未安装office的计算机上读取/编辑文档。U可以使用warm lamp.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,只有hardcore Microsoft目前不建议也不支持从任何无人参与、非交互式客户端应用程序或组件(包括ASP、ASP.NET、DCOM和NT服务)自动化Microsoft Office应用程序,因为在这种环境下运行Office时,Office可能会表现出不稳定的行为和/或死锁。
如果您正在构建一个在服务器端上下文中运行的解决方案,那么您应该尝试使用安全的组件来无人值守地执行。或者,您应该尝试找到至少允许部分代码在客户端运行的替代方案。如果使用服务器端解决方案中的Office应用程序,该应用程序将缺少许多成功运行所需的功能。此外,您将面临整体解决方案稳定性方面的风险。在文章中阅读更多关于这方面的内容
作为一种解决方法,您可以使用OpenXMLSDK,有关更多信息,请参阅。或者使用为服务器端执行而设计的任何第三方组件。例如,看一看Aspose。今天我会尽快测试您的解决方案,泰。谢谢您的提问。首先,我感到惊讶的是,我竟然选择使用OpenXMLSDK。此外,对于使用Interop正确打开的文件,我还获得了FileFormatException
(“文件包含损坏的数据”)。我无法更改文件格式,因为它是来自客户的文档输入流。我可以使用Open XML来处理在MS Word中创建并保存为.docx文件的文件吗?Open XML仅用于docx文件,将doc转换为docx(afaik)的唯一方法是打开它并用Word保存它:/如果您处理的是旧文档,那么恐怕您唯一的解决方案就是互操作。我对doc没有问题。另外,我测试了您的和@AlexeyTrofimuk解决方案,效果很好,非常感谢。OpenXml是一个非常大的库,我不想为一个不典型的操作添加这个引用,对我来说,手动解析是更好的方法。下一次我将使用OpenXml来完成类似的任务,因为它真的很有用@VadimMartynov是的,你可以用sdk做几乎所有的事情。但是,如果你只需要查看tagsTY to all的答案,它确实是相当大的。甚至有必要获得该部分(我不确定)吗?var tags=package.PackageProperties.Keywords如何;
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");