以上是我的文件夹结构。我有一个Cordova应用程序和一个Windows运行时组件 - IBscanUltimate。 include文件夹具有调用非托管IBscanUltimate.dll的C#代码。 Class1.cs是这样的:
using System;
namespace IBscanUltimate
{
public sealed class Class1
{
public static String getSDK()
{
IBscanUltimate.DLL.IBSU_SdkVersion a = new DLL.IBSU_SdkVersion();
IBscanUltimate.DLL._IBSU_GetSDKVersion(ref a);
return "SDKVersion: " + a;
}
}
IBScanUltimateApi.cs& _IBSU_GetSDKVersion看起来像这样:
internal partial class DLL
{
[DllImport("IBScanUltimate.DLL")]
private static extern int IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo);
public static int _IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo)
{
int nRc = IBSU_STATUS_OK;
nRc = IBSU_GetSDKVersion(ref pVerinfo);
return nRc;
}
}
我已将DLL放置在许多位置,以查看它是否会被拾取并且它们都具有上述属性。但是当我尝试运行我的应用程序时,它说无法找到IBScanUltimate.DLL
这就是输出的来源:
我不确定我做错了什么,为什么DLLImport找不到我的dll。谢谢你的帮助。
确切错误是:
System.DllNotFoundException: Unable to load DLL 'IBScanUltimate.DLL': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
更新#1:
我遇到过https://msdn.microsoft.com/en-us/library/windows/desktop/hh447159(v=vs.85).aspx本文解释了LoadPackagedLibrary
函数可用于加载dll。我没有看到任何关于如何在C#中使用它的例子。
更新#2:
Specify the search path for DllImport in .NET提到可以使用SetDllDirectory
或AddDllDirectory
。他有SetDllDirectory
的代码段,但参数为string[] paths
。我如何指定相对参数?
更新#3:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
public static bool setPath(String path)
{
//Windows.Storage.
//return SetDllDirectory("ms-appx:///");
return SetDllDirectory(path);
}
我尝试使用我的应用可以访问的各种位置调用SetDllDirectory(path)
方法,但我一直在" false"。我尝试的几个例子:
NativeMethods.setPath(Package.Current.InstalledLocation.Path.ToString());
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;
这是我的应用安装的地方:
C:\Users\AAA\App\hello\platforms\windows\build\windows\Debug\x64\AppX
我可以看到我的DLL就在那里。但我仍然得到无法找到DLL的异常。我是否必须在清单上加上一些内容?
更新#4: 我在DLL上运行了一个dumpbin,我在dumpbin中看到了下面的DLL:
WINUSB.DLL
mfc90.dll
MSVCR90.dll
KERNEL32.dll
USER32.dll
GDI32.dll
VERSION.dll
MSVCP90.dll
SETUPAPI.dll
我想我想分别检查上面的每个dll,看看我的Windows运行时是否可以选择它?其中一个可能是没有加载的罪魁祸首?
更新#5: 在看到 Peter Torr - MSFT 的答案,并在Google上搜索MFC后,我发现了这篇文章https://msdn.microsoft.com/en-us/library/d06h2x6e.aspx,其中指出:
The MFC classes and their members cannot be used in applications that execute in the Windows Runtime.
我想现在就结束这场疯狂的狩猎。我会关闭它,我试图加载的库依赖于不适用于Windows运行时的库。 我有这种感觉,因为Windows窗体应用程序会运行,但转换为Windows运行时的代码会给出找不到DLL的错误。感谢彼得指导正确的方向。
答案 0 :(得分:1)
您尝试加载的DLL显然是为桌面应用程序构建的(它具有用户,GDI和MFC导入),并且不能用作UWP二进制文件。我还怀疑DLL没有设置AppContainer标志(您传递给链接器的选项)。您需要找到另一种方法来完成您的需求(如有必要,请通过the Windows Platform UserVoice发出任何功能请求。
答案 1 :(得分:0)
我怀疑它可以很好地找到你的DLL,但它无法找到一个或多个依赖项。不幸的是,这两种情况都会导致非常通用的DllNotFoundException,它会提到您尝试P / Invoke的DLL。
有一种简单的方法可以找出遗漏的东西! Windows包含一个名为“loader snaps”的功能,启用该功能后,将记录Windows DLL加载程序为您的进程执行的所有操作。这意味着它还将打印无法加载的DLL。要启用它,请在管理员命令提示符下运行:
gflags.exe -i "<executableName>.exe" +sls
其中可执行文件名称只是没有该文件夹的可执行文件的名称。要查看输出,您还需要启用本机或混合模式调试器。您可以在Visual Studio中的项目属性调试选项卡中执行此操作。
您可以在此处详细了解负载快照:
https://blogs.msdn.microsoft.com/junfeng/2006/11/20/debugging-loadlibrary-failures/