#windows #boost #windows-services #boost-filesystem
#Windows #boost #windows-services #boost-файловая система
Вопрос:
У меня есть некоторый код, который перебирает файлы в каталоге и выполняет полезные действия с файлами, не относящимися к каталогу, например, так:
namespace bfs = boost::filesystem;
for (bfs::directory_iterator iterDir(m_inPath);
bContinue amp;amp; iterDir!=bfs::directory_iterator(); iterDir )
{
std::string filename = iterDir->path().filename().string();
boost::to_lower(filename);
if (!bfs::is_directory(*iterDir) amp;amp; Condition2(filename)) {
std::ifstream ifFile(iterDir->path().string().c_str());
DoUsefulThings(iterDir());
}
}
Это отлично работает в моих модульных тестах, но когда я запускаю полную программу как службу, мои тестовые каталоги (по-видимому, ошибочно) проходят !bfs::is_directory
проверку, и DoUsefulThings
проверка ifstream.good()
завершается ошибкой, равной 13.
Я попытался изменить !bfs::is_directory
на bfs::is_regular_file
(думая, что, возможно, из-за системного состояния это было что-то другое), но я получил те же результаты. is_regular_file
Условие не выполняется в каталоге в моем модульном тестировании, но проходит при запуске от имени службы.
Я также добавил try / catch в свой оператор if, чтобы проверить, не генерирует ли он исключение, и убедился, что это не так (вероятно, можно было бы использовать его в любом случае, но это не помогло с этим).
Я подумал, что проблема может быть связана с уровнем разрешений службы, поэтому я изменил свойства службы, чтобы войти в систему с той же учетной записью, которую я использую для входа в эту систему. Тот же результат. Я также немного поработал с PerformanceMonitor, чтобы попытаться получить некоторые подсказки там, но я еще не многое почерпнул из этого.
Может кто-нибудь подсказать, почему это может происходить? Ошибка = 13 == «отказано в разрешении», верно? Есть ли дополнительная проверка, которую мне нужно выполнить перед вызовом is_directory?
Я использую Windows XP, Visual Studio 2008 / C , версию 1.44 библиотеки Boost и версию 3 файловой системы.
ETA: я добавил следующее, чтобы проверить каталог вручную (направление косой черты не имело значения), и is_regular_file ведет себя так, как ожидалось:
std::string strDir = "D:/Dir1/Dir2/Dir3/Dir4/Dir5\Dir6";
if (bfs::is_regular_file(strDir))
LOG("It's a regular file"); //This does not get executed
else
LOG("Not a regular file"); //This does
У меня есть инструкции журнала, распечатывающие как * iterDir, так и iterDir-> path(), и они оба соответствуют тому, который я ввел вручную. Исключает ли это проблемы с разрешениями? Продолжу тестирование, поскольку этот результат пока не имеет для меня смысла.
Комментарии:
1. разрешения… Я предполагаю, что каталог недоступен / доступен для обхода
2. Итак, каков фактический путь к каталогу? Это может быть путь UNC, недоступный для службы, или это может быть удаленный общий ресурс, сопоставленный с диском, с отображением, невидимым для службы. Путь даст вам подсказку, почему служба его не видит.
3. Вы также можете попробовать запустить службу под учетными данными пользователя, в отличие от по умолчанию
LocalService
.4. @sehe: Я попытался вручную установить разрешения для каталога, чтобы разрешить полный доступ «всем». Я также попытался добавить другой каталог в том же месте (думая, что, возможно, другой как-то был поврежден). Оба по-прежнему передают if(bfs::is_regular_file).
5. @Роман Р. Путь действительно может быть ключом. Это формат «D:/Dir1/Dir2/Dir3/Dir4/Dir5/Dir6Dir7 «. Я изучу это и посмотрю, вызывают ли косые черты проблему. Я попытался запустить службу под теми же учетными данными, которые я использую для входа в систему, но, похоже, это ничего не изменило.
Ответ №1:
@Ennael:
не забывайте, что вам нужны разрешения на обход для всех родительских папок / узлов устройств папки, к которой вы пытаетесь получить доступ. Я думаю, что предложение Романа было бы первым в очереди, чтобы устранить сомнения (что, конечно, действительно иррационально: Errno=13 == "permission denied"
).
Вы могли бы начать оттуда с помощью таких инструментов, как
- cacls.exe
Чтобы выполнить список / редактирование ACL командной строки
- AccessEnum v1.32 для обнаружения любых изменений в разрешениях в дереве файловой системы (имеет отличную опцию, чтобы предупреждать только тогда, когда разрешения становятся более ограниченными или разрешительными)
Комментарии:
1. Я предоставил «всем» полный доступ к этому каталогу и всем его родительским каталогам, включая сам диск. Я также запускаю службу под своим логином (вместо LocalService). AccessEnum и cacls подтверждают права доступа к каталогу, и AccessEnum по-прежнему выдает мне тот же результат после повторного запуска службы. Я еще немного почитаю / подумаю об этих инструментах. Спасибо.
Ответ №2:
Бах. Это была ошибка в моем «Условии2». Спасибо за помощь.