Почему boost::filesystem is_directory возвращает разные результаты при запуске в качестве службы Windows?

#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». Спасибо за помощь.