C++ – .NET assembly not loading from NTVDM


I have a VDD dll that's loaded by a DOS program running inside the NTVDM. This dll uses C++/CLI and references a .NET assembly.

All in all, the loading process is something like this:

  NTVDM runs:
    prntsr.com which uses VDD RegisterModule to load:
      prnvdd.dll which references .NET assembly:

The prntsr.com, prnvdd.dll and prnlib.dll files are all in the same folder.

However, when loading it, I get the following exception:

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'PRNLib, Version=, Culture=neutral, PublicKeyToken=ecf23cee305e91b7' or one of its dependencies. The system cannot find the file specified.
File name: 'PRNLib, Version=, Culture=neutral, PublicKeyToken=ecf23cee305e91b7'
   at VDD_Initialise()

=== Pre-bind state information ===
LOG: User = DOMAIN\user
LOG: DisplayName = PRNLib, Version=, Culture=neutral, PublicKeyToken=ecf2
LOG: Appbase = file:///C:/WINDOWS/system32/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Post-policy reference: PRNLib, Version=, Culture=neutral, PublicKeyToken=ecf23cee305e91b7
LOG: Attempting download of new URL file:///C:/WINDOWS/system32/PRNLib.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/system32/PRNLib/PRNLib.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/system32/PRNLib.EXE.
LOG: Attempting download of new URL file:///C:/WINDOWS/system32/PRNLib/PRNLib.EXE.

It only searches C:\WINDOWS\system32\ for the assembly, which I guess this is due to NTVDM.EXE – as this is the actual process that the assembly is being loaded into, it takes its location as the AppBase.

Any ideas how to change the AppBase or otherwise work around this problem?

Best Solution

It's really not a good idea to try to pull the CLR into every instance of ntdvdm...

But probably it would work better if you made your assembly a shared assembly, since these are stored in a standard location and not looked for relative to the application?