Uhh What? DevPath is an environment variable that allows you specify global directories which are searched just like GAC. If you ever had the urge to load dlls from your application from subdirectories you need a probing element in your app.config which allows exactly that.
The only problem with that is that you cannot escape from your application root directory. When you try to load something from ..\Centralbin it is ignored. In that cases you need to use the GAC if you like it or not. Since DevPath was broken for some time with .NET 2.0 I thought it was no longer supported. But thanks to John Robbins article "PDB Files: What every Developer must know." I did learn a different story. That makes it possibly now to use some Microsoft tools in a standard fashion. The Xml Serialization assembly generator Sgen for example can create the serialization assembly only if all public serializable types do not have dependencies to assemblies in other directories. This is a major PITA since fresh compiled assemblies are located in other directories than the rest (except it you have set Copy To Local to true in Visual Studio but that is a bad idea either).
But now we can alter the sgen.exe.config and add one line
<?xml version ="1.0"?>
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
<developmentMode developerInstallation="true"/>
</runtime>
</configuration>
And now behold lets call sgen.exe
C:\Source>sgen.exe
System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Resources.ResourceManager.TryLookingForSatellite(CultureInfo lookForCulture)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
at System.Environment.ResourceHelper.GetResourceStringCode(Object userDataIn)
at System.Environment.GetResourceFromDefault(String key)
at System.Environment.GetResourceString(String key)
at System.IO.Path.CheckInvalidPathChars(String path)
at System.IO.Path.NormalizePathFast(String path, Boolean fullCheck)
at System.IO.Path.NormalizePath(String path, Boolean fullCheck)
at System.IO.Path.GetFullPathInternal(String path)
at System.AppDomainSetup.set_DeveloperPath(String value)
at System.AppDomain.SetupFusionStore(AppDomainSetup info)
at System.AppDomain.SetupDomain(Boolean allowRedirects, String path, String configFile)
Ups. .NET 3.5 SP1 did not do the trick? Some investigation shows that the .NET Framework is still subject to bad error handling. If DEVPATH is empty or DEVPATH contains invalid path characters such as > < | or " then it will try to report the issue so far so good. But it seems that Microsoft seems to be a lover of fast in process tests where each methods works perfectly but the whole thing blows apart when used in a true product scenario. This is not the first time that did happen with DEVPATH but I thought that since the release of .NET 2.0 in 2005 these things would have been fixed and some regression tests had been added. Apparently I was wrong.
In my specific case I did try set devpath="c:\Source\EntLib3Src\App Blocks\bin" which did fail because of the parenthesis. Once I removed the "invalid" characters all did work out fine.
During my investigation with Reflector I stumbled upon another undocumented environment variable RELPATH which does set the private probing path.
info.PrivateBinPath = Environment.nativeGetEnvironmentVariable(AppDomainSetup.PrivateBinPathEnvironmentVariable);
When I set it to e.g. subDir then I do no longer need to set the private probing path in my App.config. Nice that could come in handy in some scenarios.