views:

126

answers:

1

I have a C# program that is running as a CGI app in IIS on XP Pro SP3. It runs fine until I reference a library assembly class and use it in the program's code. If I run the CGI program by hand it loads and executes. But when it is run by IIS the referenced assembly fails to bind despite it being right in the same directory as the parent executable. Here's the binding log I get:

=== Pre-bind state information ===
LOG: User = STEVIENEW\IUSR_STEVIENEW
LOG: DisplayName = VOEvent, Version=3.0.7.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/
LOG: Initial PrivatePath = NULL
Calling assembly : MsgChkCGI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
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: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent.DLL.
LOG: Attempting download of new URL file://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent/VOEvent.DLL.
LOG: Attempting download of new URL file://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent.EXE.
LOG: Attempting download of new URL file://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent/VOEvent.EXE.

The Appbase is correct (though what is the '?' in the URI????? maybe that's a hint). The assembly voevent.dll is definitely right in the same directory (Appbase!) as MsgChkCGI.exe. And if I just double click the exe it stsrts up correctly (and has an error due to a missing CGI environment var, but that's expected).

Anyone know what's going on?

+2  A: 

I'm not sure why the might happen.

As a workaround, you could handle AppDomain.CurrentDomain.AssemblyResolve

EDIT: Note that if you use types from another assembly in the same method that adds the handler, the event won't fire, because the assembly will be loaded by the JITter before the code in the method is actually executed.
Therefore, you need to put any code that uses types from other assemblies in a separate method, then call that method after handling AssemblyResolve.

2nd EDIT: Call Assembly.Load(File.ReadAllBytes(path)).
Also, can you edit your question to include all of the details of the FileNotFoundException from Assembly.LoadFile?

SLaks
Interesting, I didn't know about that. Will try and get back on this. Thanks!!!
Bob Denny
It appears that this event is never fired. The problem appears to happen before the program starts to execute, not when it first tries to create a type in that referenced assembly. Thanks for trying though!
Bob Denny
Add the handler, then put _all_ of your code in a separate function and call it after the handler. It _will_ work.
SLaks
Thanks, I'll give that a try. I appreciate your persistence :-) Er, I assume you mean to add the handler to the event in Main(), then call a function which contains the entire rest of the program right after that.
Bob Denny
You assume correctly.
SLaks
It's getting hit. Now for the amazing part: I use ResolveEventArgs to identify which assembly it's trying to resolve (it is the fully qualified assy name) and construct a path to the assembly file. Then I call File.Exists() on that path, it returns true. I then use the exact same path (a string variable) in a call to Assembly.LoadFile() and it throws a System.IO.FileNotFoundException!! See above, this runs on Windows on a non-IIS webserver without jumping through these hoops. This is something being done by IIS!
Bob Denny