2

Visual Studio Templates has folder structure like this:

/ProjectTemplatesCache
    /CSharp
        /Windows
            /1033
                /ClassLibrary.zip -- the lowest subfolder
                    /Properties
                /WindowsService.zip -- the lowest subfolder
            /1042
    /VisualBasic

I want to start at the root folder, dig down to the lowest subfolders and zip each of them to a separate archive.

Using Windows Batch or C#.

How to zip - doesn't matter. Just be able to select each separately / execute a command against each.

Any ideas?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • Does the "lowest" mean that it doesn't contain subfolders? Also, are there any naming conventions which would help to get folder hierarchy? – khachik Apr 13 '11 at 09:43
  • @khachik: Good question! Thanks. I think that the lowest is which is named "*.zip" (still being a folder) – abatishchev Apr 13 '11 at 09:51

4 Answers4

5

C# 4.0:

var leafsDirs = Directory
    .EnumerateDirectories(Directory.GetCurrentDirectory(), "*", SearchOption.AllDirectories)
    .Where(sub => !Directory.EnumerateDirectories(sub).Any());

leafsDirs.ToList().ForEach(Console.WriteLine);

Look at ICSharpZip to do the actual zipping

Update:

After @khachik's suggestion my criteria should be di.Name.EndsWith(".zip", StringComparison.OrdinalIgnoreCase)

Ok, just mixing the condition with the Where()

as far as template folder can contains some subfolders, e.g. ASP.NET MVC web app

you can always provide a Func<DirectoryInfo, bool> to decide which directories are toBeZipped

sehe
  • 374,641
  • 47
  • 450
  • 633
1

If you are using C# then:

... and if you actually want to unzip, then try Unzip files programmatically in .net

Community
  • 1
  • 1
Stuart
  • 66,722
  • 7
  • 114
  • 165
  • Thanks. To archive I cant call `Process.Start("winrar.exe", args)`. My main question is not how to enumerate subfolder, but how to find the lowest one. – abatishchev Apr 13 '11 at 09:47
  • You find the lowest ones (the "leaf" directories) by recursively enumerating until you hit a directory with no more subdirectories. – Stuart Apr 13 '11 at 09:50
1

So, you essentially want to find all sub directories that in turn has no sub directories?

var root = new DirectoryInfo(startPath);
var lowestSubFolders =
    root.EnumerateDirectories("*", SearchOption.AllDirectories)
        .Where(di => di.EnumerateDirectories().Count() == 0);

Of course there will be issues if there are sub directories to which the current user does not have access and such, but I get the feeling that this code is for some convenience tool that will operate in a controlled environment.

Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
  • 2
    Like minds... However using !.Any() beats .Count()==0 especially for large / many directories – sehe Apr 13 '11 at 09:55
  • After @khachik's suggestion my criteria seems to be `di.Name.EndsWith(".zip")` as far as template folder can contains some subfolders, e.g. ASP.NET MVC web app – abatishchev Apr 13 '11 at 09:57
1

This code below recursively goes through a directory tree. You should be able to use it as a basis for your code:

void WalkDirectoryTree(System.IO.DirectoryInfo root)
{
    System.IO.FileInfo[] files = null;
    System.IO.DirectoryInfo[] subDirs = null;


    // First, process all the files directly under this folder
    try
    {
        files = root.GetFiles("*.*");
    }
    // This is thrown if even one of the files requires permissions greater
    // than the application provides.
    catch (UnauthorizedAccessException e)
    {
    }
    catch (System.IO.DirectoryNotFoundException e)
    {
    }

    if (files != null)
    {
      foreach (System.IO.FileInfo fi in files)
      {

      }

      // Now find all the subdirectories under this directory.
      subDirs = root.GetDirectories();


      foreach (System.IO.DirectoryInfo dirInfo in subDirs)
      {
        // Resursive call for each subdirectory.
        WalkDirectoryTree(dirInfo);
      }
    }
}

You can just return a bool if there are no more directories to go down and then zip all the files.

Remy
  • 12,555
  • 14
  • 64
  • 104