Search code examples
c#wpdunmanagedexports

PortableDeviceManagerClass in C# not able to initialize


I have a c# library which provides some functionallity to upload data onto connected (android) devices. The dll itself gets exported via UnmangedExports to be used by an delphi application.

Here is the function which gets called by the delphi application:

[DllExport]
[return: MarshalAs(UnmanagedType.LPStr)]
public static string getDevices()
{
    try
    {
        var devices = string.Empty;
        var collection = new PortableDeviceCollection();
        collection.Refresh();

        foreach (var device in collection)
        {
            device.Connect();
            if (devices != string.Empty)
            {
                devices += ";";
            }
            devices += device.FriendlyName;
            device.Disconnect();
        }
        return devices;
    }
    catch (Exception e)
    {
        SomeClass.WriteErrorToLogFile(e);
        return "ERROR";
    }
}

Here is the class PortableDeviceCollection:

public class PortableDeviceCollection : Collection<PortableDevice>
{
    private readonly PortableDeviceApiLib.PortableDeviceManagerClass _deviceManager;

    public  PortableDeviceCollection()
    {
        this._deviceManager = new PortableDeviceApiLib.PortableDeviceManagerClass();
    }

    public bool Refresh()
    {
        this._deviceManager.RefreshDeviceList();
        // Determine how many WPD devices are connected
        var deviceIds = new string[1];
        uint count = 1;
        this._deviceManager.GetDevices(null, ref count);
        if (count > 0)
        {
            // Retrieve the device id for each connected device
            deviceIds = new string[count];
            this._deviceManager.GetDevices(deviceIds, ref count);
            foreach (var deviceId in deviceIds)
            {
                Add(new PortableDevice(deviceId));
            }
            return true;
        }
        else
            return false;
    }
}

I can create the dll with visual studio and use this inside of the delphi application. When the delphi application calls the getDevices() function, i get an error on the instantiation of the PortableDeviceCollection class:

The file or assembly "Interop.PortableDeviceApiLib, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null" or a dependency of it was not found. The assembly is created by a runtime that is more recent than the currently loaded runtime and can not be loaded.

ProductXY.PortableDeviceCollection..ctor()
ProductXY.ProductXYMain.getDevices()

The targetframework for the c# project is set to .Net Framework 4. Using any lower version i get an error when i try to compile the project:

The primary reference "Interop.PortableDeviceApiLib" could not be resolved because it has an indirect dependency on the .NET Framework assembly "mscorlib, version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089", which is a higher version 4.0.0.0 than version 2.0.0.0 in the current target framework.

Please note. I have neither written the c# library nor the delphi application. Both have worked together for years. Now i have to add a functionallity to the c# library. I have not added any code to the project. I just tried to compile it again and use the dll. The only thing i did was updating the RGiesecke.DLLExport.Metadata via NuGet Packetmanager. Without updating i got an error

"Microsoft.Build.Utilities.ToolLocationHelper could not find ildasm.exe"

I am aware of this Enumerating Windows Portable Devices in C# question. But my error is thrown before the code which is treaded by the question is reached. I still tried the solution to the question, but the action (deassamble, find and replace in the dll) which is described in the answere has already been done (otherwise my code would not have compiled).

The error message doesn't make sense to me. Interop.PortableDeviceApiLib is a COM-Lib which is not available for download in different framework-versions. I think I am missing something here.

Can anyone help me?


Solution

  • I was finally able to solve this problem. To be honest I don't know what finally solved this. For every one who stumbles up on this, here are the things i tried to fix this problem. They are in no specific order (since i tried everything multiple times):

    • Updating the RGiesecke.DLLExport packet
    • Changing the plattform in the Konfigurations-Manager to x86
    • Disassamble, edit and reassable the Interop.PortableDeviceApiLib like in this question (answeres of Christophe Geers and Bruno Klein)
    • Delete the reference to the Interop.PortableDeviceApiLib
    • Delete the reference to the Interop.PortableDeviceTypesLib
    • Readding the reference to the Interop.PortableDeviceApiLib
    • Readding the reference to the Interop.PortableDeviceTypesLib
    • Rebuild the project
    • Setting the Interoptyp embeddet on both to false (I found various statements to NOT do this, but the project was set up like this when i got it and it worked (be carefull)) on both Interop-Libs.

    At least this helped me.