Why does boost::filesystem is_directory return different results when run as a Windows Service?
I have some code that iterates through files in a directory and does useful things with the non-directory files, like so:
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().st开发者_运维知识库ring().c_str());
DoUsefulThings(iterDir());
}
}
This works fine in my unit tests, but when I run the full program as a service, my test directories (seemingly erroneously) get past the !bfs::is_directory
check and DoUsefulThings
's ifstream.good()
check fails, with an errno of 13.
I tried changing !bfs::is_directory
to bfs::is_regular_file
(thinking that maybe there was a system condition causing it to be something else), but I got the same results. The is_regular_file
condition fails on the directory in my unit test but passes when run as a service.
I also added a try/catch around my if statement to see if it was throwing an exception and verified that it wasn't (probably could use one anyway, but didn't help with this).
I considered that the problem could be related to the service's permissions level, so I changed the properties of the service to log on as the same account that I use to log in to that system. Same result. I've dabbled with PerformanceMonitor some as well to try to get some clues there, but I haven't gleaned much from it yet.
Can someone suggest why this might be happening? Errno=13 == "permission denied", right? Is there an additional check I need to perform before calling is_directory?
I'm using Windows XP, Visual Studio 2008/C++, version 1.44 of the Boost library, and version 3 of filesystem.
ETA: I added the following to test the directory manually (the direction of the slash marks didn't make a difference), and is_regular_file behaves as expected:
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
I have log statements printing out both *iterDir and iterDir->path() and they both match the one I put in manually. Does this rule out permissions issues? Will continue testing, as this result doesn't really make sense to me yet.
@Ennael:
don't forget that you need traversal permissions on all the parent folders/device nodes of the folder you are trying to access. I think Roman's suggestion would be first in line to eliminate the doubt (which, of course is really irrational: Errno=13 == "permission denied"
).
You could start from there with a tools like
- cacls.exe
To do commandline ACL listing/editing
- AccessEnum v1.32 to detect any changes in permissions across a filesystem tree (has a nifty option to only warn when permissions get more restricted or more permissive)
Bah. It was a bug in my "Condition2". Thanks for the help.
精彩评论