Проверьте, защищен ли файл Excel паролем в.NET Core
Технология:
C#
ASP.NET Core 2.0
Excel (в основном OpenXml, но иногда устаревший документ)
В настоящее время используется ExcelDataReader для чтения файлов.
Сценарий:
Мне нужно хранить некоторые файлы на сервере и обращаться к ним позже, чтобы сделать работу. Пользователи загружают файлы через веб-API и совершают звонки, запрашивая работу таким же образом.
Некоторые пользователи защищают свои файлы Excel паролем, и требуется, чтобы эти файлы оставались защищенными паролем на сервере.
Проблема:
Мне нужно определить, защищен ли документ паролем, чтобы я мог использовать соответствующую конфигурацию для доступа к нему.
Я немного погуглил, но в основном это Workbook.HasPassword (я думаю, что это часть Excel.Interop, которую я бы не хотел добавлять). Я также нашел эту ссылку на аналогичный вопрос в документах Office, в котором решением был длинный контрольный список для различных данных заголовка через файловый поток.
В идеале, я хотел бы получить решение, дружественное к ядру, которое не требует от меня открытия файла. Я не часто работаю с документами, поэтому не знаю, где искать дальше.
Какие-либо предложения?
3 ответа
Поскольку вы уже используете ExcelDataReader, откройте файл в предложении try-catch и обработайте его. InvalidPasswordException
:
bool ExcelFileRequiresPassword(Stream stream) {
try {
using (ExcelReaderFactory.CreateReader(stream)) { }
} catch (InvalidPasswordException) {
return true;
}
return false;
}
Это не слишком плохая производительность. За кулисами он проверяет только соответствующие заголовки в файле и обрабатывает все подробности BIFF, ZIP и версий. Данные не будут прочитаны, если нет пароля.
Вы не узнаете, защищен ли файл паролем, не открывая файл. Эта информация находится в файле (насколько я знаю); это не выставлено в файловой системе.
Вы должны быть в состоянии быстро добиться этого, используя OpenXml SDK. Создайте незащищенный файл. Скопируйте это. Откройте копию, установите пароль и сохраните его. Затем используйте openXml "Productivity Tool", чтобы различать два файла ("Compare Files", вверх на панели инструментов). Это должно быстро сосредоточиться на том, где искать.
Это старый пост, который я добавляю к нему, но недавно я хотел установить, защищены ли электронные таблицы паролем на C# без использования внешней библиотеки. В итоге я создал следующий код.
Могут быть случаи и форматы файлов, которые я не нашел, но я надеюсь, что это поможет вам встать на правильный путь.
ПРИМЕЧАНИЕ . Количество пробелов в сравнительном тексте важно, поэтому будьте осторожны при вырезании и вставке.
static bool IsExcelPasswordProtected(string strSource)
{
bool blResult = false;
if (File.Exists(strSource))
{
char[] chBuffer = new char[4096]; // The character strings usually occur within the first 2K in my testing, but just in case
TextReader trReader = new StreamReader(strSource, Encoding.UTF8, true);
// Read the buffer
trReader.ReadBlock(chBuffer, 0, chBuffer.Length);
trReader.Close();
// Remove non-printable and unicode characters, we're only interested in ASCII character set
for (int i = 0; i < chBuffer.Length; i++)
{
if ((chBuffer[i] < ' ') || (chBuffer[i] > '~')) chBuffer[i] = ' ';
}
string strBuffer = new string(chBuffer);
// .xls format files, version 97 to 2003 contains this text when password protected
if (strBuffer.Contains("M i c r o s o f t E n h a n c e d C r y p t o g r a p h i c P r o v i d e r"))
{
blResult = true;
}
// .xlsx format files contain this text when password protected
else if (strBuffer.Contains("E n c r y p t e d P a c k a g e"))
{
blResult = true;
}
// .xlsx format files contain this text when not password protected
else if (strBuffer.Contains("[Content_Types]"))
{
blResult = false;
}
// .xlsx format files contain this text when not password protected
else
{
blResult = false;
}
}
else
{
// File not found...deal with as you wish
}
return (blResult);
}