Friday, February 26, 2010

Directory Search with multiple filters in .Net

Directory.GetFiles in .Net 3.5 and Directory.EnumerateFiles in .Net 4.0 neither supports multiple patterns when searching for files. The reason is that it uses FindFirstFile / FindNextFile of kernel32.dll which lacks the support.

Initial thought would be to create an extension method to the Directory class, but since it’s a static class that’s not possible. The second best choice is to create a short helper class instead. What we do is do a wildcard search with “*” and filter the results with a regular expression.

If you return a large result set the new Enumerable version in .Net 4.0 is preferable as it returns values to act on as you go along.

public static class MyDirectory
// Works in .Net 3.5 - you might want to create several overloads
public static string[] GetFiles(string path, string searchPatternExpression, SearchOption searchOption)
if (searchPatternExpression == null) searchPatternExpression = string.Empty;
Regex reSearchPattern = new Regex(searchPatternExpression);
return Directory.GetFiles(path, "*", searchOption).Where(file => reSearchPattern.IsMatch(Path.GetFileName(file))).ToArray();

// Works in .Net 4.0 - inferred overloads with default values
public static IEnumerable<string> GetFiles(string path, string searchPatternExpression = "", SearchOption searchOption = SearchOption.TopDirectoryOnly)
Regex reSearchPattern = new Regex(searchPatternExpression);
return Directory.EnumerateFiles(path, "*", searchOption).Where(file => reSearchPattern.IsMatch(Path.GetFileName(file)));

// Works in .Net 4.0 - takes same patterns as old method, and executes in parallel
public static IEnumerable<string> GetFiles(string path, string[] searchPatterns, SearchOption searchOption = SearchOption.TopDirectoryOnly)
return searchPatterns.AsParallel().SelectMany(searchPattern => Directory.EnumerateFiles(path, searchPattern, searchOption));

Wednesday, February 17, 2010

Blazing fast IPC in .Net 4: WCF vs. Signaling and Shared Memory

[Update 2011-02-02: Did a test against NamedPipeServerStream and NamedPipeClientStream which i mention in a comment at the end]

An MSDN article from 2007 compares the speed of WCF vs. .Net Remoting, and shows the speed increase WCF gives over remoting in an IPC scenario using named pipes as transport. With the introduction of the System.IO.MemoryMappedFiles namespace in .Net 4 and a blog post by Salva Patuel which outlines that almost all communication inside windows uses memory mapped files at it’s core, I had to try this myself with the new capabilities in the .Net 4 framework.

Friday, February 12, 2010

I want to copy those files! – A tale on how to get files from a “locked down” virtual machine over RDP

I recently attended a course where we first connected to a virtual machine thru a custom application, then connected to the VM via RDP.

The VM had a folder full of lab exercises which would be nice to have locally for reference. But how could I move these files? The VM’s were not on internet so file transfer to a repository on the internet was out of the questions.

Mapping up local drives were also blocked, which it should for security reasons. The only available mechanism which carried data back and forth from my local machine to the VM was the clipboard.

An idea is born!

Since this was a developers course and we had Visual Studio available it was actually a no brainer.

  1. Zip up the labs folder in explorer
  2. Run the following code:
    static void Main(string[] args)
    string base64 = Convert.ToBase64String(File.ReadAllBytes(@"C:\Student\"));
    File.WriteAllText(@"C:\Student\labs.txt", base64);
  3. Open up the base64 encoded file in visual studio
  4. Copy the content to the clipboard
  5. Paste the clipboard to a text file locally
  6. Run the following code to decode it all:
    static void Main(string[] args)
    string base64 = File.ReadAllText(@"c:\temp\labs.txt");
    File.WriteAllBytes( @"c:\temp\", Convert.FromBase64String(base64) );
Presto, and the lab files were transferred.