这个问题与一个旧问题密切相关:Windows Form Designer: Could not load file or assembly,但没有给出所需的答案。
我的问题如下。我有一个自定义控件,我想在 .NET 的 WinForms 项目中使用它。除此之外,该控件需要
opencv
的一些功能。因此,我有一个非托管 C++ 类来处理对 opencv
的所有调用。我们称之为 Unmanaged.dll
然后,我有一个 C# 包装器,它使用互操作调用非托管 C++,我们称之为 CSharpWrapper.dll
。 CSharpWrapper
正在工作,并且所有依赖项(Unmanaged.dll
和 opencv_worldXXX.dll
)都使用 <Content Include="path/to/dll"><CopyToOuputDircetory>PreserverNewest</CopyToOuputDirectory></Content>
模式复制到输出目录中。
使用
CSharpWrapper
的 ui 代码继承自 System.Windows.Forms.Control
。我们称之为MyCanvas
。当我构建应用程序时,它工作得很好(再次将所有依赖项复制到应用程序输出目录中),但是,当我使用 Visual Studio 将 MyCanvas
组件从表单工具箱拖放到表单设计器中时,Visual Studio 会报告构建 Unmanaged.dll
中指向的对象的行上出现 Dll 未找到异常。
我上面链接的答案告诉我在哪里可以找到 Visual Studio 填充的 dll 缓存,这些缓存是设计器使用的表单、控件、画布等所需的依赖项。果然,当我查看
C:\Users\<user>\AppData\Local\Microsoft\VisualStudio\17.0_8106eeaf\ProjectAssemblies
时,有一个包含 CSharpWrapper.dll
和 CSharpWrapper.pdb
的哈希文件夹。但不存在任何非托管依赖项,因此使用 Designer 时会出现运行时异常。通过手动将依赖项复制到该目录中,设计者感到满意并且一切正常。
但这只是一个黑客。而且,更糟糕的是,如果我不做黑客工作,每次我编辑带有
MyCanvas
的表单时,它都会重新生成 .Designer.cs 文件并删除所有对 MyCanvas
的引用。那就不好了。
那么,有没有办法让 Visual Studio 自动将我的非托管 dll 放入
ProjectAssemblies
缓存目录中?
编辑:
我已经尝试在
DesignMode
的构造函数中测试 MyCanvas
,以便它应该跳过召唤丢失的 Dll,但由于某种原因它仍然会抛出。通过将调试器从 Visual Stuio 的另一个实例附加到我的项目并在 Designer 中启动控件,果然 DesingMode
是 false
。这是代码(.NET Framework 4.8):
class MyCanvas:Control
{
private CSharpWrapper wrapper = null;
public MyCanvas() : base()
{
if(!DesignMode) // <- false when using Designer for some reason
wrapper = new CSharpWrapper(); // <- summons Unmanaged.dll here
}
}