1

enter image description here

Above is my folder structure. I have a Cordova app and a Windows Runtime Component - IBscanUltimate. The include folder has the C# code calling into the unmanaged IBscanUltimate.dll. Class1.cs is like this:

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

The IBScanUltimateApi.cs & _IBSU_GetSDKVersion look something like this:

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

enter image description here

I have placed the DLL in many locations to see if it'll get picked up and they all have the above properties. But when I try to run my app, it says unable to locate the IBScanUltimate.DLL

This is how the output is coming:

enter image description here

enter image description here

I am not sure what is it that I am doing wrong and why the DLLImport cannot find my dll. Thank you for your help.

Exact error is:

System.DllNotFoundException: Unable to load DLL 'IBScanUltimate.DLL': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Update #1: I have come across https://msdn.microsoft.com/en-us/library/windows/desktop/hh447159(v=vs.85).aspx This article is explaining that LoadPackagedLibrary function can be used to load the dll. I am not seeing any example on how to use this in C#.

Update #2: Specify the search path for DllImport in .NET Mentions that SetDllDirectory or AddDllDirectory can be used. He has a code snippet for SetDllDirectory, but the argument is string[] paths. How would I specify the relative argument?

Update #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);
}

I tried calling the SetDllDirectory(path) method with various locations that my app should have access to but I am keep getting "false". Few examples that I have tried:

NativeMethods.setPath(Package.Current.InstalledLocation.Path.ToString());
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;

This is where my app is installed: C:\Users\AAA\App\hello\platforms\windows\build\windows\Debug\x64\AppX and I can see that my DLL is there. But still I'm getting the exception that DLL cannot be found. Do I have to put something on the manifest regarding this?

Update #4: I ran a dumpbin on the DLL and i see the below DLL in the dumpbin:

WINUSB.DLL
mfc90.dll
MSVCR90.dll
KERNEL32.dll
USER32.dll
GDI32.dll
VERSION.dll
MSVCP90.dll
SETUPAPI.dll

I guess I'd like to check on each dll above separately to see if my windows runtime can pick it? One of them could be the culprit that's not being loaded?

Update #5: Upon seeing the answer from Peter Torr - MSFT, and googling for MFC I came across this article https://msdn.microsoft.com/en-us/library/d06h2x6e.aspx Which states:

The MFC classes and their members cannot be used in applications that execute in the Windows Runtime.

I guess to conclude this wild hunt now. I would close this up that the library I tried to load is dependent on libraries not available for Windows Runtime. I had this feeling because Windows form application would run but the the code converted to Windows Runtime would give the error that the DLL is not being found. Thanks to Peter for guiding in the right direction.

Community
  • 1
  • 1
Noman
  • 887
  • 1
  • 15
  • 34
  • Changed the C# project. I did not understand your question about the file name. I pasted the properties screenshot as well if that's what you wanted. It still gives me the same error; cannot find the DLL. – Noman Mar 14 '17 at 17:03
  • Are you talking about the closed project: IBscanUltimateWRT? – Noman Mar 14 '17 at 22:59
  • I got rid of that project upon seeing your comment regarding name conflict, created a new windows runtime project called IBsWRT. – Noman Mar 15 '17 at 16:50
  • @Norman: you captured "devenv.exe". That's not your application, that's Visual Studio. Sorry, I can't help you. – Thomas Weller Mar 15 '17 at 18:56
  • @Noman did you checked these links - http://stackoverflow.com/questions/28620082/use-an-unmanaged-dll-in-apache-cordova-project http://stackoverflow.com/questions/39626809/calling-windows-managed-dll-from-cordova-app-winrt-component – Gandhi Mar 17 '17 at 15:57
  • The first link; that guy seems to be stuck. But that's pretty much what I'm doing. They're actually both stuck :( – Noman Mar 17 '17 at 16:00
  • Have you tried this with the latest dev version of cordova-windows platform? `cordova platform rm windows && cordova platform add https://github.com/apache/cordova-windows` – daserge Mar 21 '17 at 08:19

2 Answers2

1

The DLL you are trying to load was clearly built for desktop apps (it has User, GDI, and MFC imports) and will not work as a UWP binary. I suspect also that the DLL does not have the AppContainer flag set (an option you pass to the linker). You will need to find another way to accomplish what you need (if necessary, please make any feature requests via the Windows Platform UserVoice.

Peter Torr - MSFT
  • 11,824
  • 3
  • 18
  • 51
  • So I will not be able to use this DLL for windows app store? But the User.dll I have been able to use. Why can't I use the other ones? – Noman Mar 20 '17 at 18:10
  • A small number of User32 APIs are supported (dealing with mouse and keyboard input) but the majority are not. Even if they "work" today they might break in the future - be sure to run the WACK tool on your app if you try to use pre-built boundaries. – Peter Torr - MSFT Mar 21 '17 at 18:57
0

I suspect that it can find your DLL just fine, but it fails to find one or more of its dependencies. Unfortunately, both of these cases result in extremely generic DllNotFoundException that mentions the DLL your try to P/Invoke to.

There is an easy way to figure out what's missing! Windows contains a feature called "loader snaps", which, when enabled, will log all the things that Windows DLL loader does for your process. That means it will also print what DLLs it fails to load. To enable it, run this in admin command prompt:

gflags.exe -i "<executableName>.exe" +sls

Where executable name is just the name of your executable without the folder. To see the output, you will also need to enable either native or mixed mode debugger. You can do that in your project properties debugging tab in Visual Studio.

You can read more about load snaps here:

https://blogs.msdn.microsoft.com/junfeng/2006/11/20/debugging-loadlibrary-failures/

Sunius
  • 2,789
  • 18
  • 30
  • But I have an .appx package. How would I use this on .appx? – Noman Mar 16 '17 at 21:27
  • .appx package ultimately still contains an executable. It will probably match your main project name. – Sunius Mar 18 '17 at 19:38
  • No, .appx is not "exactly" an exe file. Or rather, I'm not sure how to do glfags on .appx, its giving error that it cannot do gflags on .appx. – Noman Mar 19 '17 at 20:08
  • .appx is just a slightly modified zip file. There is an .exe file inside. And you enable gflags on that .exe file, not on an .appx. – Sunius Mar 20 '17 at 09:19
  • No, there is not .exe file inside .appx. – Noman Mar 20 '17 at 13:26
  • Not sure how you looked, but it must be there. Run your application. Find it in task manager. It will tell you the .exe name. – Sunius Mar 20 '17 at 13:27
  • I don't know what kind of project you're running. There must be some of kind of confusion. I have a cordova project, it creates an appx package. There is not ".exe" associated with this type of project. – Noman Mar 20 '17 at 14:23
  • Please check https://superuser.com/questions/681510/where-is-the-executable-file-of-windows-store-application – Noman Mar 20 '17 at 15:55