14

The Background:

I have an application that needs to run on clients whose installed .NET frameworks range all the way from 2.0 up to 4.5. This application has to be able to enumerate and perform operations on large numbers of files (in excess of 200k discrete files, in select cases).

To build the index of files, the application currently uses System.IO.DirectoryInfo.GetFiles(). This comes at a performance hit, as the processing component has to wait for the entirety of the Path tree to be indexed before it can start work. Due to some archaic tape multiloaders and some poorly written firmware, traversing some directories can trigger reads from tapes - jacking the processing time from tens of seconds to tens of minutes.

.NET 4.0 provides the System.IO.Directory.EnumerateFiles(Path) method, which alleviates this problem. However, only a few of the datter consoles have been upgraded to 4.0+, and our pleas to modernize have been met with hostility.

The Question:

Is it possible to implement methods for both GetFiles and EnumerateFiles in a single binary? Effectively, this would be a single binary targeted to .NET 2.0, with the ability to call a .NET 4.0 method if it was determined at runtime that the 4.0 framework was available.

Before it's mentioned: changing out the datters is not an option to our client. I've tried. Have I ever tried.

Ed Penwell
  • 163
  • 5
  • 1
    If they refuse to upgrade then there's really nothing that you can do to fix the issue. To answer your question, this is not possible. – Dennis Rongo Jan 29 '13 at 21:08
  • 6
    You could write your own implementation of EnumerateFiles() in .Net 2, I should think. – Matthew Watson Jan 29 '13 at 21:09
  • What you *might* be able to do is put the different code in different sub assemblies and then decide which to call after determining the .NET runtime version installed. Though this might require that the main program is built against the latest version - thus leaving you in exactly the same position. – ChrisF Jan 29 '13 at 21:10
  • You can do the differentiation at install time with some custom actions in the installer – Sten Petrov Jan 29 '13 at 21:11
  • If this were possible, you could use reflection, but since .net 4.0 is a different run time i'm thinking this probably won't work. – jbtule Jan 29 '13 at 21:12
  • This question might be helpful if this is a possibility for you. http://stackoverflow.com/questions/2382927/can-i-use-a-net-4-0-library-in-a-net-2-0-application Targeting both frameworks or conditionally targeting is not possible to my knowledge. – Gray Jan 29 '13 at 21:10
  • So you can implement your functionality using System.IO.Directory.EnumerateFiles(Path) in a .NET4.0 assembly, make it COM visible, and then use this COM component in your .NET2.0 application. However this would require having .NET4.0 installed on each machine and you describe that this is not possible. – Adrian Ciura Jan 29 '13 at 21:45
  • @AdrianCiura There are a few ways I could work around this: Check for .NET 4.0 or later at runtime to determine wheter to use the COM component, or call the COM component in a try and failover to the GetFiles method. However, at the end of the day the most elegant solution is to just use WinAPI, as Govert said. – Ed Penwell Jan 31 '13 at 19:38

1 Answers1

10

You won't be able to (easily) make a single binary that works on .NET 2.0 and uses the .NET 4.0 methods. There are all kinds of roundabout ways - reflection etc., but those seem like a bad idea in your case.

However, there's no reason why you can't make your own implementation for EnumerateFiles in a .NET 2.0 library. For this you'd make P/Invoke calls to the WIN32 functions FindFirstFile and FindNextFile. Two CodeProject projects look like they cover this area, and should have the right bits in the source:

Govert
  • 16,387
  • 4
  • 60
  • 70
  • +1 - I agree. I just decompiled `Directory.EnumerateFiles()` and while it spans multiple classes, it wouldn't be that hard to copy the implementation (or just use the core Win32 calls). – Tim M. Jan 29 '13 at 21:18
  • Reflection seems like a much better option than PInvoke – Sten Petrov Jan 29 '13 at 21:35
  • There's no way you can use reflection to do this easily. P/Invoke to do this, however, is really very easy (if you've ever programmed using the Windows API). – Matthew Watson Jan 29 '13 at 21:43