Can´t load mpusbapi.dll on C# .NET WPF project - c#

I need to build a gui to communicate via bulk USB from my Windows PC to a PIC microcontroller. I'm trying to use mpusbapi.dll as I see over diferent tutorials on internet, but I can´t acommplish to succesfully reference the dll in my project. VS 2015 show me this error: "mpusbapi.dll" could not be added. Make sure that the file is accessible, and that its a valis assembly or COM component.
I did research and i figured out the problem was the unmanaged dll, so I tried to reference via DllImport. But at this time, that did not work either.
I share my code below expecting someone could help me or give me some reference to a better way to accomplish my objective with usb.
using System.Runtime.InteropServices;
namespace GUI_ROBOT
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
//Problem here
[DllImport("mpusbapi.dll",CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 MPUSBGetDLLVersion();
[DllImport("mpusbapi.dll")]
static extern UInt32 MPUSBGetDeviceCount(string pVID_PID);
private void btnStart_Click(object sender, RoutedEventArgs e)
{
try
{
string dCount = MPUSBGetDLLVersion().ToString();
listBox1.Items.Add(dCount);
}
catch (Exception j)
{
System.Windows.MessageBox.Show("Error: " + "\nMessage = " +
j.Message);
}
}
}
}
The try catch statetment give me the follow result:
Error after try catch statetment
Translate "Can´t load the .dll file 'mpuasbapi.dll': Can´t find the specified module."
I don´t undesrtand because I just added the file in my project.
Thanks people!

The problem was that the .dll have not being copied to the output folder, as Fruchtzwerg said. So I just changed the properties of the .dll file as I say in the comments.
Then [see comments] I had a 32-bit / 64-bit conflict with the mpusbapi.dll The problem was solve using this answer:Could not load file or assembly ... An attempt was made to load a program with an incorrect format (System.BadImageFormatException)

Related

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?
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.

App with embedded dll wont run on another computer

Ok so built this app and it's an assignment so I wanted to embed some dll in it so I would only have one file when submitting it. The dll is only used for some UI controls and visuals, nothing else
I went through the necessary steps of setting Copy Local to false under references and setting Build Action to Embedded Resource but the problem I have is that if I copy the application exe to another pc it won't run unless I copy the referenced dll into the same directory of the exe so it seems to me that it's not loading the embedded dll file or I may have set up something wrong
Just to note though, the app does run fine on my pc, the one I created on, without needing the referenced dll next to the exe file.
Here is the code I used:
//other using statements
using System.Reflection;
using library; //<--- reference to embedded dll
namespace app {
public partial class Form1 : Form1 {
[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(int i);
private string embeddedFile = "app.library.dll";
public Form1() {
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
InitializeComponent();
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
using(var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedFile)) { //<-- debugging shows a System.IO.UnmanagedMemoryStream exception here
byte[] assemblyData = new byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
}
///
/// some unrelated code
///
}

Converting a C# Console App to a DLL

I am rewriting the Betfair API to JSON from SOAP and I have started off the way I did it before as a console APP which is then called from a task scheduler or win service.
However now I have been asked to do various different jobs with the code and I don't want to write a console app for each job (different sites want prices, bets placed etc)
The new codebase is much larger than the old one and I would have been able to copy the 4 files from the old system into a DLL app and then create various console apps/services to implement the DLL - however because it's 40+ files I don't want a copy n paste job if possible.
Is there a way I can EASILY convert an existing console project into a class / DLL project with some tool or command in VS?
I want to be able to just then create simple apps that just go
BetfairBOT myBOT = new BetfairBOT()
myBOT.RunGetPrices();
or
BetfairBOT myBOT = new BetfairBOT()
myBOT.RunPlaceBets();
e.g 2/3 lines of code to implement my DLL that is registered to my app.
So without copy and paste can I do this.
I am using VS 2012, .NET 4.5 (or 4.0 if I need to depending on server), Windows 8.1
Any help would be much appreciated.
This answer is from here. while it used winforms instead of console application, I think you will be able to use it.
Steps for creating DLL
Step 1:- File->New->Project->Visual C# Projects->Class Library. Select your project name and appropriate directory click OK
After Clicking on button ‘OK’, solution explorer adds one C# class ‘Class1.cs’. In this class we can write our code.
When we double click on Class1.cs, we see a namespace CreatingDLL. We will be use this namespace in our project to access this class library.
Step 2:- Within Class1.cs we create a method named ‘sum’ that takes two integers value and return sum to witch method passed numbers.
using System;
namespace CreatingDLL
{
public class Class1
{
/// <summary>
/// sum is method that take two integer value and return that sum
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public int sum(int x, int y)
{
return x + y;
}
}
}
Step 3:- Now build the Application and see bin\debug directory of our project. ‘CreatingDLL.dll’ is created.
Now we create another application and take this DLL (CreatingDLL.dll) reference for accessing DLL’s method.
Steps for accessing created DLL
Step 4:- File->New->Project->Visual C# Projects->Windows Form Application.
Step 5:- Designed windows form as bellow figure.
Step 6:- Add reference of DLL (CreatingDLL) which we created before few minutes.
After adding reference of DLL, following windows will appear.
Step 7:- Write code on button click of Windows Form Application. Before creating object and making method of Add DLL, add namespace CreatedDLL in project as bellow code.
using System;
using System.Windows.Forms;
using CreatingDLL;
namespace AccessingDLL
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
Class1 c1 = new Class1();
try
{
txtResult.Text = Convert.ToString(c1.sum(Convert.ToInt32(txtNumber1.Text), Convert.ToInt32(txtNumber2.Text)));
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Step 8:- Now build the application and execute project and see output.
Edit: To change an application into a library do these steps
First, double click on Properties inside Solution Explorer window.
Then, On the openned page, change the Output Type from Console Application to Class Library

Providing path to externals assembly native dll dependecy

I have C# application which loads set of managed assemblies. One of this assemblies loads two native dlls (each of them in different location) if they are avaiable. Iam trying to find way to provide search path to those native dlls.
Are there other options? I really dont want to provide those dlls with my software - copying them to programs directory of course solves the problem.
I've tried using SetDllDirectory system function but it is possible to provide only one path using it. Each call to this function resets path.
Setting PATH enviroment variable does not solve the problem too :/
I know this was an old post, but just so there's an answer: Using the LoadLibary function you can force load a native DLL:
public static class Loader
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string fileName);
}
You must call this before any other DLL does - I usually call it in a static constructor of my main program. I had to do this for DllImport(), and static constructors were always executed before the native DLLs were loaded - they only load actually the first time an imported function is called.
Example:
class Program
{
static Program()
{
Loader.LoadLibrary("path\to\native1.dll");
Loader.LoadLibrary("otherpath\to\native2.dll");
}
}
Once the library is loaded it should satisfy the DllImports() of the other managed assemblies you are loading. If not, they might be loaded using some other method, and you may have no other option but to copy them locally.
Note: This is a Windows solution only. To make this more cross-platform you'd have to detect operating systems yourself and use the proper import; for example:
[DllImport("libdl")]
public static extern IntPtr DLOpen(string fileName, int flags);
[DllImport("libdl.so.2")]
public static extern IntPtr DLOpen2(string fileName, int flags);
// (could be "libdl.so.2" also: https://github.com/mellinoe/nativelibraryloader/issues/2#issuecomment-414476716)
// ... etc ...
This could help:
private void Form1_Load(object sender, EventArgs e)
{
//The AssemblyResolve event is called when the common language runtime tries to bind to the assembly and fails.
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);
}
//This handler is called only when the common language runtime tries to bind to the assembly and fails.
Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string dllPath = Path.Combine(YourPath, new AssemblyName(args.Name).Name) + ".dll";
return (File.Exists(dllPath))
? Assembly.Load(dllPath)
: null;
}
Register yours dlls to GAC. More here.

Open a dialog box from a DLL

I have a Visual Studio 2008 solution with two projects: a C# Windows Forms application and a C++ DLL. The DLL opens a custom CFileDialog. Here is a toy version that demonstrates the problem, where the C# app is just a button to launch the dialog and a label to show its result:
DialogApp.cs:
...
public partial class Form1 : Form {
...
[DllImport("DialogDll.dll")]
static extern int OpenDialog();
...
private void button1_Click(object sender, EventArgs e) {
int r = OpenDialog();
label1.Text = r.ToString();
}
}
DialogDll.h:
extern "C" {
__declspec(dllexport) int __cdecl OpenDialog();
}
DialogDll.cpp:
#include <afxdlgs.h>
#include "DialogDll.h"
extern int __cdecl OpenDialog() {
CFileDialog d(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("All Files (*.*)|*.*||"), NULL);
if (d.DoModal() == IFOK) {
return 4;
} else {
return 9;
}
}
When I run this, I get an error about a debug assertion failing, asking to Abort|Retry|Ignore. The assertion is afxCurrentResourceHandle != NULL. How do I get rid of this problem? If I click Ignore, I get my dialog, and everything appears to work fine.
I've already tried following the instructions here:
http://msdn.microsoft.com/en-us/library/7a51wcfx.aspx
These directions say the problem is that a DLL doesn't have a CWinApp object, and I should add AFX_MANAGE_STATE(AfxGetStaticModuleState()) to the beginning of each function call. I did that, and had to resolve a linker issue by following the directions here, manually specifying the entry point for my DLL: http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/0b154e1c-141f-4567-bb24-1ac7c8ee2713/ (The parts about changing the order of the .libs didn't work for me.)
But now I'm getting another error:
LoaderLock was detected:
Attempting managed execution code inside OS Loader Lock. Do not attempt to run
managed code inside a DllMain or image initialization function since doing so
can cause the application to hang.
Good grief! Am I even going in the right direction? I've done years of programming, but I'm pretty new to the Windows platform. I think after all this work, my question is still pretty simple: How do I open a CFileDialog from my dll?
You are probably going in the right direction. I am assuming that you want/need to use MFC in your DLL.
The WinApp and MANAGE_STATE advice was good.
Are you throwing /clr or /clr:pure on any of your C++ source files? Why? Does your C++ DLL mix managed and native code together?
The fix for this trivial app is to not throw /clr. This will make all your C++ code native and ensure that you are not at risk of calling managed static initialisers from the loader lock.
Martyn
Please see comment above, but I would recommend as my answer:
Use System.Windows.Forms.OpenFileDialog instead OR
Use GetOpenFileName

Categories