Home All Groups Group Topic Archive Search About

Dynamically loading DLLs dynamically that have dependencies...

Author
13 Jul 2006 6:42 PM
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

Author
13 Jul 2006 6:56 PM
Barry Kelly
"Dan Dorey" <dandor***@gmail.com> wrote:

> 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

Are all your drivers up to date? click for free checkup

Author
13 Jul 2006 6:57 PM
Thomas T. Veldhouse
Dan Dorey <dandor***@gmail.com> wrote:
Show quoteHide quote
> 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>

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE  34D0 D69D 1EDC D5EC AED1
Author
13 Jul 2006 7:48 PM
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
Author
13 Jul 2006 7:57 PM
Thomas T. Veldhouse
Dan Dorey <dandor***@gmail.com> wrote:
>
> 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?

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE  34D0 D69D 1EDC D5EC AED1
Author
13 Jul 2006 8:16 PM
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!

Thomas T. Veldhouse wrote:
Show quoteHide quote
> Dan Dorey <dandor***@gmail.com> wrote:
> >
> > 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?
>
> --
> Thomas T. Veldhouse
> Key Fingerprint: 2DB9 813F F510 82C2 E1AE  34D0 D69D 1EDC D5EC AED1
Author
13 Jul 2006 8:19 PM
Thomas T. Veldhouse
Dan Dorey <dandor***@gmail.com> wrote:
> 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.

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE  34D0 D69D 1EDC D5EC AED1

Bookmark and Share