I have been asked a few times why, when you run our wizard, we generate C++ code and not C# or VB. Some have even tried creating a C# or VB stub exe only to find errors when their program is run. Why does this happen?
A file that is put into the GAC when you install the VS Shell Isolated components is Microsoft.AppEnv.CustomLoader.dll. When a transition is made from your exe to appenvstub.dll a few things happen to get the VS Shell running; one of the first is loading and then modifying how the CLR will find and load components. When you run Visual Studio all the files are within a self contained directory, usually \Program Files\Microsoft Visual Studio 9\Common7\IDE or a sub directory. But when you run your program it can be installed anywhere, and most likely will not be in the same directory as devenv.exe. Because your code and our code will not be in the same place, packages and support code that we install will not be found, and not everything will work as expected.
To fix this, we created a custom loader. The .NET framework has the ability to modify how AppDomains are configured when created, and one of these configuration points is to allow a callback when an assembly cannot be found. The custom loader hooks this call back and, when an assembly cannot be found, calls our loader to help locate the assembly. The problem with this is that you need to set this callback before the AppDomain is created, and the properties of the AppDomain cannot be modified after creation. Since a majority of the Visual Studio .NET Framework code runs in the default AppDomain, you need to hook this callback before the default AppDomain has been created.
If you were to create a stub exe using C# or VB, just running your exe causes the default AppDomain to be created. Since there can be only one copy of the .NET Framework loaded into a single process and because the default AppDomain has been created (and cannot be destroyed), our custom loader will never have the chance to load. So while you could try to write a stub in C# or VB, you would find that shortly after running parts of your Shell would start to fail and not work properly because we could not find all the assemblies that we need to run.