3
votes

I have a mixed mode dll with native dll dependencies.

I am loading the mixed mode dll from a C# exe using Assembly.Load. However, the location of the mixed mode dll is not in the application bin directory, therefore it fails because it only looks for the native C++ dll's in the bin and the folders in the PATH environment variable.

I thought using the option /assemblylinkresource was suppose to stop this and force the native dll's to be found in the alternate directory alongside the deployed mixed mode dll. This is proving to be not correct.

Is there a way to create a multi-file assembly with native dll's using an existing C++/CLI mixed mode dll? The only examples (http://msdn.microsoft.com/en-us/library/xawyf94k(v=vs.100).aspx) I've seen are using .netmodules coupled with a native dll.

Therefore, the solution is to either:

a) some how force the application to search for native dependencies in a directory of your choosing; or b) package the native dll's into the one managed mixed mode assembly (is this even possible??) - given statically linking the dependencies is not an option.

2

2 Answers

5
votes

Normal Windows DLL searching rules apply. So yes, there's no hope it will ever find those DLLs. A "multi-file assembly" isn't going to work either, you cannot merge native code. Options you have, roughly in preferred order:

  • Call SetDllDirectory() to add the path that contains the DLLs to the set of directories where Windows will look. May fail if the external code uses it as well.
  • Use Environment.SetEnvironmentVariable() to append the path to the PATH environment variable. This only changes the process' copy of the PATH so is a reasonable approach. May fail on machines that have a bloated PATH that is reaching the limit.
  • Set Enviroment.CurrentDirectory to the path with the DLLs. May fail if the external code tinkers with it as well.
  • Record the path for each DLL at install time in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs registry key.
  • Install the DLLs in the Windows side-by-side cache and use a manifest to tell Windows about it. This is hard to get right.
2
votes

Potential candidate for a solution, not tested with MMA: This is probably not the optimal solution you were hoping for, but I thought I would add it as it could help you along the way to achieve solution a). In c++ you could control loading path and path search order by either manually setting the directory to be searched using SetDllDirectory (only available from XP SP1) or by manually loading the dll using LoadLibraryEx.

I guess one could use P/invokes to get access to these calls in C#

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern void SetDllDirectory(string lpPathName);