Thread overview
windows 8.1 and dirEntries
Dec 26, 2013
Stephen Jones
Dec 26, 2013
thedeemon
Dec 26, 2013
Stephen Jones
Dec 26, 2013
Ali Çehreli
Dec 27, 2013
Stephen Jones
December 26, 2013
Code that was fine on 32 bit XP is ow crashing Windows 8.1:

foreach(string s; dirEntries(directory, SpanMode.shallow)){
  if(endsWith(s, "~")) continue;
  try{
    if(isDir(s)) d ~= s;
  }catch(FileException e){   }finally{}
  try{
    if(isFile(s)){
      if(endsWith(s, sufix)){
        f ~= s;
      }	
    }
  }catch(FileException e){}finally{}
}

The error I receive is:

Bypasses std.file.FileException@std\file.d(2262)
===Bypassed===
std.fileFileException@std\file.d(2262): c:\User\Administrator\: Access Denied


The crash occurs when directory is the string:
c:\Documents and Settings
c:\PerfLogs
c:\System Volume Information

but there is no issue opening:
c:\Program Files

I am on a 64 bit machine compiling into 32 bit but wouldn't any problem there be caught in the try .. catch block? And how come the try .. catch block is being bypassed?
December 26, 2013
On Thursday, 26 December 2013 at 15:37:01 UTC, Stephen Jones wrote:
> foreach(string s; dirEntries(directory, SpanMode.shallow)){

Try
  dirEntries(directory, SpanMode.shallow, false)
because the problematic folders you mentioned might be symlinks.

I've got an app which can scan whole drive (https://bitbucket.org/infognition/undup) and there I used this way of calling dirEntries and catching FileException was enough to work fine in Windows 8.1. However I haven't tried yet to compile with DMD 2.064, some earlier version was used. Which compiler and what mode (release/debug) did you use?
December 26, 2013
> I've got an app which can scan whole drive (https://bitbucket.org/infognition/undup) and there I used this way of calling dirEntries and catching FileException was enough to work fine in Windows 8.1. However I haven't tried yet to compile with DMD 2.064, some earlier version was used. Which compiler and what mode (release/debug) did you use?

I have DMD32 v2.062 debug. I also tried:

foreach(string s; dirEntries(directory, SpanMode.shallow, false)){...

and am getting the same crashing on certain folders.
December 26, 2013
On 12/26/2013 07:36 AM, Stephen Jones wrote:

> Code that was fine on 32 bit XP is ow crashing Windows 8.1:

Actually, it is not a crash. The program is telling us that something it was asked to do cannot be accomplished. A function throws an exception, nobody catches it, and the program ends due to an unhandled exception.

> foreach(string s; dirEntries(directory, SpanMode.shallow)){
>    if(endsWith(s, "~")) continue;
>    try{
>      if(isDir(s)) d ~= s;
>    }catch(FileException e){   }finally{}
>    try{
>      if(isFile(s)){
>        if(endsWith(s, sufix)){
>          f ~= s;
>        }
>      }
>    }catch(FileException e){}finally{}
> }
>
> The error I receive is:
>
> Bypasses std.file.FileException@std\file.d(2262)
> ===Bypassed===
> std.fileFileException@std\file.d(2262): c:\User\Administrator\: Access
> Denied

I think the user who is running the program does not have access rights to open Administrator's directory. (The rest of my post assumes that it is an access right issue.)

> wouldn't any problem there be caught in the try .. catch block?
> And how come the try .. catch block is being bypassed?

Maybe the exception is being thrown during the foreach iteration, outside of your two try-catch blocks. I would try putting a try-catch block around the entire foreach statement.

If that works and if skipping the problematic entries is an option, use an explicit while (or for) loop so that you can catch it more precisely:

import std.stdio;
import std.file;

void main()
{
    auto dirRange = dirEntries("/tmp/deneme", SpanMode.shallow);

    while (!dirRange.empty) {
        writeln(dirRange.front);
        dirRange.popFront();
    }
}

Now you can put a try-catch around individual range operations: construction, empty, front, and popFront().

Ali

December 27, 2013
Thanks Ali. Stupid of me, it is the dirEntries call that opens the directory and tries to read contents. I did this (below), but it still leaves the odd situation that Documents and Settings cannot be opened, and surely non-administrators have access to this folder.

try{
  auto dirs =  dirEntries(directory, SpanMode.shallow, false);

  foreach(DirEntry ent; dirs){
    if(ent.isDir) d ~= ent.name;
    if(ent.isFile){
      if(endsWith(ent.name, sufix)) f ~= ent.name;
    }
  }
}catch(FileException ex){
  writeln("Error reading directory, probably no administrator privilege");
} finally{}