Dynamically loading DLLs dynamically that have dependencies...

D

Dan Dorey

I actually have two questions here, but I'll start by giving an outline
of what I'm trying to do.

I'm building an app with a simple plugin architecture (all in the same
app domain). I have each plugin in a separate sub-dir inside a
"Plugins" directory. Each plugin consists of at least two DLLs (a
controller and a driver). However, most drivers also rely on other
external DLLs.

In one particular case this dependency is to a C++ DLL called
PF_DTMF_Connector.dll which in turn is dependent on another C/C++ DLL
in the windows\system32 folder.

My first question is what this error message means and how can I
resolve it? When I dynamically load my driver DLL up for this
particular plugin I get the error message below. Note that if I include
my driver code as a normal project, I don't get this error. Also note
that although I do get this error, at least some of the functionality
of this DLL DOES work. This DLL is located right with the plugin using
it. Is this DLL having trouble finding it's dependent DLL that's in the
windows\system32 directory? If so, how would I correct this?

at System.Reflection.Assembly.nLoad(AssemblyName fileName, String
codeBase, Evidence assemblySecurity, Assembly locationHint,
StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean
forIntrospection)
[Could not load file or assembly
'file:///C:\working\IQ\v6.0\DTMFTester\bin\Debug\Plugins\Enumeration\PF_DTMF_Connector.dll'
or one of its dependencies. The module was expected to contain an
assembly manifest.] :
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef,
Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean
forIntrospection)
at System.Reflection.Assembly.InternalLoadFrom(String assemblyFile,
Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm
hashAlgorithm, Boolean forIntrospection, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)

My second question relates to another plugin I wrote. It's driver DLL
depends on another (managed) DLL. When I put this dependent DLL in the
same directory as the plugin, it can't find it. If I move this
dependent DLL to the root directory of the application it all works
fine. How can I get it to seach the directory that the plugin is in? I
tried using the <probe> attribute in the app.config but without any
luck.

Any direction with either of these problems would greatly be
appreciated!

Dan
 
B

Barry Kelly

Dan Dorey said:
In one particular case this dependency is to a C++ DLL called
PF_DTMF_Connector.dll which in turn is dependent on another C/C++ DLL
in the windows\system32 folder.
[Could not load file or assembly
'file:///C:\working\IQ\v6.0\DTMFTester\bin\Debug\Plugins\Enumeration\PF_DTMF_Connector.dll'
or one of its dependencies. The module was expected to contain an
assembly manifest.] :

A normal C++ DLL is not an assembly, so it cannot be loaded by
Assembly.LoadFrom(). If you use it via P/Invoke, it will be loaded
automatically.
My second question relates to another plugin I wrote. It's driver DLL
depends on another (managed) DLL. When I put this dependent DLL in the
same directory as the plugin, it can't find it. If I move this
dependent DLL to the root directory of the application it all works
fine. How can I get it to seach the directory that the plugin is in? I
tried using the <probe> attribute in the app.config but without any
luck.

You can either create a new AppDomain and use the PrivateBinPath of
AppDomainSetup, or you can use Assembly.LoadFrom and hard-wire a path,
or you can hook up to the AppDomain.AssemblyResolve() event.

-- Barry
 
T

Thomas T. Veldhouse

Dan Dorey said:
I actually have two questions here, but I'll start by giving an outline
of what I'm trying to do.

I'm building an app with a simple plugin architecture (all in the same
app domain). I have each plugin in a separate sub-dir inside a
"Plugins" directory. Each plugin consists of at least two DLLs (a
controller and a driver). However, most drivers also rely on other
external DLLs.

In one particular case this dependency is to a C++ DLL called
PF_DTMF_Connector.dll which in turn is dependent on another C/C++ DLL
in the windows\system32 folder.

My first question is what this error message means and how can I
resolve it? When I dynamically load my driver DLL up for this
particular plugin I get the error message below. Note that if I include
my driver code as a normal project, I don't get this error. Also note
that although I do get this error, at least some of the functionality
of this DLL DOES work. This DLL is located right with the plugin using
it. Is this DLL having trouble finding it's dependent DLL that's in the
windows\system32 directory? If so, how would I correct this?

at System.Reflection.Assembly.nLoad(AssemblyName fileName, String
codeBase, Evidence assemblySecurity, Assembly locationHint,
StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean
forIntrospection)
[Could not load file or assembly
'file:///C:\working\IQ\v6.0\DTMFTester\bin\Debug\Plugins\Enumeration\PF_DTMF_Connector.dll'
or one of its dependencies. The module was expected to contain an
assembly manifest.] :
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef,
Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean
forIntrospection)
at System.Reflection.Assembly.InternalLoadFrom(String assemblyFile,
Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm
hashAlgorithm, Boolean forIntrospection, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)

This is telling you that you are trying to load a non-assembly DLL (not all
DLLs are assemblies). You should use DLL Imports and link directly.
My second question relates to another plugin I wrote. It's driver DLL
depends on another (managed) DLL. When I put this dependent DLL in the
same directory as the plugin, it can't find it. If I move this
dependent DLL to the root directory of the application it all works
fine. How can I get it to seach the directory that the plugin is in? I
tried using the <probe> attribute in the app.config but without any
luck.

Any direction with either of these problems would greatly be
appreciated!

Try putting this in your App.config and make sure the directory name is
relative to the root of your application (your application must be the root of
the tree and ../../../somedir is not allowed).

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<probing privatePath="bin"/>

</assemblyBinding>
</runtime>
 
D

Dan Dorey

This is telling you that you are trying to load a non-assembly DLL (not all
DLLs are assemblies). You should use DLL Imports and link directly.

Thanks both of you for your responses. The snippet for the app.config
fixed the problem my second question was addressing. I'm still stuck on
the first one however.

I'll give a bit more detail for the first problem.

I'm dynamically loading only a managed DLL that I wrote called
EnumerationDriver. It is automatically loading the dependent DLLs for
me under the hood.

EnumerationDriver.dll (managed -- this is the only one I'm dynamically
loading)
DTMFEngine.dll (managed)
PF_DTMF_Connector.dll (unmanaged C++)
M_DTMF.dll (unmanaged C/C++ in the windows\system32 directory).

EnumerationDriver.dll --> DTMFEngine.dll --> PF_DTMF_Connector.dll -->
M_DTMF.dll

DTMFEngine.dll uses a standard DLL import to access
PF_DTMF_Connector.dll

Should I be using a different method of dynamically loading my DLLs?

Thanks again,
Dan
 
T

Thomas T. Veldhouse

Dan Dorey said:
DTMFEngine.dll uses a standard DLL import to access
PF_DTMF_Connector.dll

The error you posted in your original post clearly shows that .NET is trying
to load the PF_DTMF_Connector.dll as a .NET assembly rather than linking in
via PInvoke (using DLLImport). Perhaps you are mistakenly loading
PF_DTMF_Connector.dll rather than DTMFEngine.dll from EnumerationDriver.dll?
Could it be a simple as an incorrect entry in your configuration file?
 
D

Dan Dorey

Thomas,

You're absolutely right! This makes a lot more sense to me now. I was
just trying to load every DLL in the directory so of course it would
try to load those ones as well!

Thanks for your help!
 
T

Thomas T. Veldhouse

Dan Dorey said:
Thomas,

You're absolutely right! This makes a lot more sense to me now. I was
just trying to load every DLL in the directory so of course it would
try to load those ones as well!

Thanks for your help!

You are welcome! I wish I had known this group had an active participation a
long while back.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top