У меня есть файл .docx
с пользовательскими свойствами, указанными только для файлов MS Office.
Если я попытался открыть тот же файл на компьютере без установленного MS Office, то на вкладке сведений о файле нет свойства «Теги».
Мне нужно прочитать Tags
в моем коде С#.
Я попробовал это решение и получил индекс 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, которые потребляют ресурсы и блокируют файл. У меня много обработчиков работало одновременно и потом я не могу отделить "левые" инстансы от нормально отработанных и чистых ресурсов.
Это причина поиска альтернативного решения. Есть ли способ прочитать определенные (пользовательские) свойства, такие как Tags
, без использования Office.Interop
?