Doug Moore
Doug Moore

Reputation: 1048

FileNotFoundException: Could not load file or assembly

I have a dll (Tracker.dll) compiled from C# and need to use it in native C++. I have that problem solved; since I cannot modify the C#, I am writing a managed C++ wrapper and exporting the classes accordingly. For a (simplified) example:

TrackerWrapper.h

#pragma once

#include <memory>

class __declspec(dllexport) TrackerWrapper {
  public:
    TrackerWrapper();
    ~TrackerWrapper();
    void Track();
  private:
    struct Impl;
    std::unique_ptr<Impl> pimpl;
};

TrackerWrapper.cpp

#using "Tracker.dll"

#include "TrackerWrapper.h"
#include <msclr\auto_gcroot.h>

using namespace System::Runtime::InteropServices;

struct TrackerWrapper::Impl {
  msclr::auto_gcroot<Tracker^> tracker;

  Impl() : tracker(gcnew Tracker()) {}
  ~Impl() {}
};

TrackerWrapper::TrackerWrapper() : pimpl(new Impl()) {}
TrackerWrapper::~TrackerWrapper() {}

void TrackerWrapper::Track() {
  pimpl->tracker->Track();
}

Main.cpp

#include "TrackerWrapper.h"
int main() {
  TrackerWrapper tracker;
  tracker->Track();
  return 0;
}

As long as all of the objects and binaries are in the same directory, after compiling with

cl /clr /LD TrackerWrapper.cpp
cl Main.cpp TrackerWrapper.lib,

everything runs perfectly. However, ideally we need the Tracker.dll as well as TrackerWrapper.lib and TrackerWrapper.dll to be in a separate directory, e.g. bin.

So, the directory structure might look like:

bin\
  Tracker.dll
  TrackerWrapper.dll
  TrackerWrapper.lib
  <other objects>

Main.cpp
TrackerWrapper.h
TrackerWrapper.cpp

I can get everything to compile by adding bin to my %PATH%, %LIB% and %LIBPATH% environment variables (or on the command line at compile time via /link and /AI), but when I execute the resulting executable I get the following error:

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Tracker, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
  at TrackerWrapper.Impl.{ctor}(Impl* )
  at TrackerWrapper.{ctor}(TrackerWrapper* )

I have tried changing #using "Tracker.dll" to a relative as well as an absolute path, but I get the same problem.

Any ideas?

Upvotes: 0

Views: 2618

Answers (2)

Matt
Matt

Reputation: 6050

Two things you can try:

  1. Check if there's inner exception in FileNotFoundException, if does, it might give you details.
  2. Monitor the process with process monitor from System internal, it can will log all file activity of the the process, from the log, you can tell which file is missing. Remember to the set the filter to only monitor your process, other wise it will monitor all processes.

Upvotes: 1

Gusman
Gusman

Reputation: 15161

Your library is loaded by the .net infrastructure and it only searches by default at the app directory or at the GAC.

If your app were .net then you can specify a library path in the App.config but as your app is native don't know if the mixed dll will load the App.config or not, may be you can try.

From MSDN:

You can use the < probing > element in the application configuration file to specify subdirectories the runtime should search when locating an assembly.

If that does not work then your last option is to add the libraries to the GAC, but the library will not really be in the specified folder but copied to the GAC's folder.

Upvotes: 0

Related Questions