Почему boost :: filesystem is_directory возвращает разные результаты при запуске в качестве службы Windows? - PullRequest
2 голосов
/ 11 октября 2011

У меня есть некоторый код, который перебирает файлы в каталоге и делает полезные вещи с файлами, не являющимися каталогами, например:

namespace bfs = boost::filesystem;
for (bfs::directory_iterator iterDir(m_inPath); 
     bContinue && iterDir!=bfs::directory_iterator(); iterDir++)
{
    std::string filename = iterDir->path().filename().string();
    boost::to_lower(filename);

    if (!bfs::is_directory(*iterDir) && 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, чтобы попытаться получить некоторые подсказки, но я пока что мало что почерпнул из этого.

Может кто-нибудь подсказать, почему это может происходить? Errno = 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 (), и они оба совпадают с теми, которые я ввел вручную. Исключает ли это проблемы с разрешениями? Продолжу тестирование, так как этот результат для меня пока не имеет смысла.

Ответы [ 2 ]

2 голосов
/ 12 октября 2011

@ Ennael:

не забывайте, что вам нужны разрешения на обход для всех родительских папок / узлов устройств той папки, к которой вы пытаетесь получить доступ.Я думаю, что предложение Романа было бы первым в очереди, чтобы устранить сомнение (что, конечно, действительно иррационально: Errno=13 == "permission denied").

Вы можете начать с таких инструментов, как

  • cacls.exe

Для создания / редактирования ACL командной строки

  • AccessEnum v1.32 для обнаружения любых изменений в разрешениях в дереве файловой системы (имеет изящную опцию для предупреждения, только когда разрешения становятся более ограниченными или более разрешающими)
0 голосов
/ 12 октября 2011

Ба.Это была ошибка в моем "Condition2".Спасибо за помощь.

...