Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Is there a native|portable tool that can give me an unicode (or at least system local-compatible) list of all files and directories under a path recursively, without recursing into junction points or links, in Windows?

For example, the built-in dir command, as well as takeown and icacls run into an infinite loop with the Application Data directory (1).

EDIT I would like to be able to get a text file or at least easy clipboard transfer as output.

share|improve this question
    
I would like to avoid using a scripting language (eg. python's os.walk), because I'd prefer a solution more easily portable (eg. a smaller single-file tool) –  naxa Jan 5 '13 at 11:00
    
Oh, and the tool should handle paths with spaces. :) –  naxa Jan 5 '13 at 11:13
    
Note the text file doesn't have to be 'plain', it can be xml, csv, tsv, or anything text. –  naxa Jan 5 '13 at 11:16
2  
I believe you could do this with robocopy, using the /L flag to prevent it from actually doing any copying. –  Harry Johnston Jan 7 '13 at 2:24
    
@HarryJohnston indeed, with robocopy /XJ /L /E <dir> <dummy-target>, the /XJ flag skips the junctions and the /L causes to list only! /E is for recursion. Problem: too verbose. But it can be made slightly better with a win32 build of gnu's grep: robocopy /XJ /L /E <dir> <dummy-target> | grep -i "new dir\|new file". Still needs "applying" the containing directory for each file. –  naxa Mar 22 '13 at 12:56

3 Answers 3

up vote 2 down vote accepted

This was somehow a hard question. Even StackOverflow has only fancy solutions.
But here is a simple one for listing all files recursively without junction folder loops.

Use PowerShell and test each file if it contains the attribute "ReparsePoint"

function Recurse($path) {

  $fc = new-object -com scripting.filesystemobject
  $folder = $fc.getfolder($path)

  foreach ($i in $folder.files) { $i | select Path }

  foreach ($i in $folder.subfolders) {
    $i | select Path        
    if ( (get-item $i.path).Attributes.ToString().Contains("ReparsePoint") -eq $false) {        
        Recurse($i.path)
    }
  }
}

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$outputlist = Recurse($scriptPath) | Out-File -Filepath .\outputlist.txt 
  1. Paste the code into a text file and save it as PowerShell (.ps1) script
  2. Place the script inside your desired folder to list all files+folder recursively
  3. Execute the script with PowerShell. A new file called outputlist.txt at the same location will appear

Quick comparison between the Powershell script and a common batch command

powershell  - good, no indefinite loops

enter image description here

batch "DIR /B /S" - bad, indefinite loops through junctions points

enter image description here

share|improve this answer
    
To test it, I've just created a junction with sysinternals tool junction.exe in a folder to itself, and unfortunately for me Directory List & Print did get into recursion. –  naxa Jan 5 '13 at 12:37
    
@naxa A late response. But better late, then never. –  nixda Aug 18 '13 at 17:15
    
I love the fact that you sorted it out, and it just works! Thanks nixda! As my original problem was gone (and I don't tend to keep a powershell at home), it took me too some time but I've finally tested it and it works just like I wanted!! Also, I'm absolutely fond of better late than never myself. :) –  naxa Sep 26 '13 at 11:05
    
For powershell beginners like me, powershell -ExecutionPolicy Unrestricted -File <yourfilename-here.ps1> will execute the script (my file association was set to notepad :).) –  naxa Sep 26 '13 at 11:06
    
Well, actually, now that I think of it, I think my original problem was never finished... it got to a point but now it's actually on hold. Hey, thanks, now I can finish the project. :D –  naxa Sep 26 '13 at 11:15

Using powershell more succinctly:

$items = @(pwd);
while($items){ $newitems = $items | Get-ChildItem | Where-Object -Property Attributes -NotLike *ReparsePoint*; $newitems; $items = $newitems | Where-Object -Property Attributes -Like *Directory* }

To get this all into a text file, just surround the whole thing with parenthesis and pipe it into out-file.

( $items = @(pwd); while($items){ $newitems = $items | gci | where -Property Attributes -NotLike *ReparsePoint*; $newitems; $items = $newitems | where -Property Attributes -Like *Directory* } ) out-file myfile.txt
share|improve this answer

From a CMD prompt:

dir /A:-L /S /B

EDIT: While this won't list the actual junction in the directory it resides, it will recurse down the junction.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.