FileNotFoundException:无法加载文件或程序集

FileNotFoundException: Could not load file or assembly

本文关键字:文件 程序集 加载 FileNotFoundException      更新时间:2023-10-16

我有一个从c#编译的dll (Tracker.dll),需要在本机c++中使用它。我已经解决了这个问题;因为我不能修改c#,所以我正在编写一个托管的c++包装器并相应地导出类。对于一个(简化的)示例:

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 <msclrauto_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;
}

只要所有的对象和二进制文件都在同一目录下,在使用

编译后
cl /clr /LD TrackerWrapper.cpp
cl Main.cpp TrackerWrapper.lib,

一切都运行得很好。然而,理想情况下,我们需要Tracker.dll以及TrackerWrapper.libTrackerWrapper.dll放在一个单独的目录中,例如bin.

因此,目录结构可能看起来像:
bin
  Tracker.dll
  TrackerWrapper.dll
  TrackerWrapper.lib
  <other objects>
Main.cpp
TrackerWrapper.h
TrackerWrapper.cpp

我可以通过将bin添加到%PATH%, %LIB%%LIBPATH%环境变量(或在编译时通过/link/AI在命令行上)来编译所有内容,但是当我执行结果可执行文件时,我得到以下错误:

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* )

我已经尝试将#using "Tracker.dll"更改为相对路径以及绝对路径,但我得到同样的问题。

任何想法?

你可以尝试两件事:

    检查FileNotFoundException是否有内部异常,如果有,它可能会给你详细信息。
  1. 从系统内部使用进程监视器监视进程,它可以记录进程的所有文件活动,从日志中,您可以知道哪个文件丢失了。记住将过滤器设置为只监视您的进程,否则它将监视所有进程。

你的库是由。net基础架构加载的,默认情况下它只在app目录或GAC中搜索。

如果你的应用程序是。net,那么你可以在app .config中指定一个库路径,但由于你的应用程序是本机的,不知道混合dll是否会加载app .config,也许你可以尝试。

从MSDN:

可以使用<元素文件来指定运行时在定位时应该搜索的子目录一个组装。>

如果这不起作用,那么你的最后一个选择是将库添加到GAC中,但是库将不会真正在指定的文件夹中,而是复制到GAC的文件夹中。