Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I created DLL with C# .NET Framework 4.5 and the build on Any CPU. I want to use this DLL to read the motherboard and Hard Drive Serial number. After I copy my DLL to the Library Folder of Meta trader (for mql4 and 5) and import it to my Custom Indicator, my app does not have the error on the compile but when I run with the debugging on the real data, the message box shows:
critical error occurred. debugging is stopped.

Also, when I drag and drop it on chart, the Indicator loads successfully but shows nothing. (When I remove DLL, the Indicator works fine).

What I have tried:

C#
using System.Management;
namespace SystemInformation
{
    public class SystemInfo
    {
        public string GetMotherboardSerialNumber()
        {
            using (var searcher = new ManagementObjectSearcher
                  ("SELECT SerialNumber FROM Win32_BaseBoard"))
            {
                foreach (var queryObj in searcher.Get())
                {
                    return queryObj["SerialNumber"].ToString();
                }
            }
            return string.Empty;
        }

        public string GetStorageDeviceSerialNumber()
        {
            using (var searcher = new ManagementObjectSearcher
                  ("SELECT SerialNumber FROM Win32_DiskDrive 
                    WHERE MediaType='Fixed hard disk media'"))
            {
                foreach (var queryObj in searcher.Get())
                {
                    return queryObj["SerialNumber"].ToString();
                }
            }
            return string.Empty;
        }
    }
}

and this is my custom indicator part for DLL:
mql5
#import "SystemInformation.dll"
string GetMotherboardSerialNumber();
string GetStorageDeviceSerialNumber();
#import

int OnInit()
  {      
      string motherBoard = GetMotherboardSerialNumber();
      
      string hardDrive = GetStorageDeviceSerialNumber();
      Alert(motherBoard + " " + hardDrive);
       return(INIT_SUCCEEDED);
}


Also when I set debug point on OnInit. When the pointer reads the string motherboard line, the app is crashed. I also checked the option, tools for checking the allow DLL import and it is checked. And I test my DLL on the one test C# program and it worked fine. How can I fix this? Please help.
Posted
Updated 3-Nov-23 7:45am
v2
Comments
Richard MacCutchan 2-Nov-23 5:06am    
Where is the code for the GetMotherboardSerialNumber method? You also need to check that it actually returns a valid string. Chances are that it did not return anything, which caused your code to crash.
Member 11400059 2-Nov-23 5:17am    
you can see GetMotherboardSerialNumber method in my code clearly. also i said this in my question too: and I test my DLL on the one test C# program and worked fine.
Richard MacCutchan 2-Nov-23 6:15am    
My apologies I was looking at the wrong section.

But GetMotherboardSerialNumber is a member of the SystemInfo class, you you need an object instance of that class to use its method.
Member 11400059 2-Nov-23 8:08am    
yes, but as I know and read the the document, in MQL after Import DLL you should wright the method you want use between the import tags, so you can use this on your code. if there is another way beside this, I do not know yet.
Richard MacCutchan 2-Nov-23 9:25am    
See my answer below.

Sorry, I know nothing about MQL. However looking at the code you have, you are declaring the two methods as local to the module that you call them from. But since those methods do not exist, that is probably the cause of the error. The #import statement should define all external method names as being part of the dll, so you should not need the local declarations. So your code should probably be something like:
C#
#import "SystemInformation.dll"

int OnInit()
{
    SystemInfo sysinfo = new SystemInfo();
    string motherBoard = sysinfo.GetMotherboardSerialNumber();
  
    string hardDrive = sysinfo.GetStorageDeviceSerialNumber();
    Alert(motherBoard + " " + hardDrive);
    
    return(INIT_SUCCEEDED);
}
 
Share this answer
 
Comments
Dave Kreskowiak 2-Nov-23 9:46am    
As far as I could tell, it seems MQL doesn't know what a class is and every example I've seen (admittedly few of them) has the MQL exposed methods declared as static. I could be wrong. I'm not about to dive into the documentation on this crap.
Richard MacCutchan 2-Nov-23 10:09am    
I had a (cursory) look at the MQL documentation and it suggests that it does. But, as I said above, I reaally know nothing about it. Maybe one of us will get confirmation.
Dave Kreskowiak 2-Nov-23 10:16am    
I saw someone mention that it doesn't. Such is the life on a poorly documented language and environment.

Yeah, maybe one of the other regulars has this thing running around and can confirm.
Member 11400059 2-Nov-23 11:25am    
as I know MQL 4 is not the Object Oriented Programming Language so your suggest is not working for it. MQL 5 but has support OOP but is very limited so it is not work on that too. also I find that the MQLs created base on C++ or C.
Richard MacCutchan 2-Nov-23 12:50pm    
Well, I did say that I know nothing about MQL. My suggested answer was based on looking at their documentation. I assumed that you knew how it works.
Where to begin. Basically, from the examples I've seen, you've got most of your code wrong to work with MQL5.

First, the methods in your SystemInfo class have to be marked "static":
C#"
using System.Management;

namespace SystemInformation
{
    public class SystemInfo
    {
        public static string GetMotherboardSerialNumber()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard"))
            {
                foreach (var queryObj in searcher.Get())
                {
                    return queryObj["SerialNumber"].ToString();
                }
            }
            return string.Empty;
        }

        public static string GetStorageDeviceSerialNumber()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_DiskDrive WHERE MediaType='Fixed hard disk media'"))
            {
                foreach (var queryObj in searcher.Get())
                {
                    return queryObj["SerialNumber"].ToString();
                }
            }
            return string.Empty;
        }
    }
}

Next, your MQL5 code has to be changed to be able to use the resulting .DLL:
MQL5
#import "SystemInformation.dll"

int OnInit()
  {
      string motherboard = SystemInfo::GetMotherboardSerialNumber();
      
      string hardDrive = SystemInfo::GetStorageDeviceSerialNumber();
      Alert(motherBoard + " " + hardDrive);
      return(INIT_SUCCEEDED);
}

THIS IS NOT TESTED CODE! I do not have any MQL5 environment to test with, nor do I want one.
 
Share this answer
 
Comments
Member 11400059 2-Nov-23 11:40am    
thank you this is worked for mql5. but in mql4 I get the error "'SystemInfo' - import not defined. can you help me on that too? please.
Dave Kreskowiak 2-Nov-23 19:10pm    
I have no idea. What I came up with is from examples I found on the web. I have no idea why this doesn't work for MQL4.
Member 11400059 3-Nov-23 2:45am    
thank you and finally I find the solution for mql4 too. but have tricky point for string return value. I write the solution for this right now.
Thank to @Dave-KreskowiakWatch I find the MQL5 solution. and now I Find the solution for mql4 too.
you can use this 2 link for the start: https://www.mql5.com/en/forum/353293[^]
Calling a DLL from MQL | Andres Jaimes[^]
first of all we should put the output project on x86 and .NET framework 3.5. also need install package unmanaged exports for nugget. because the MQL4 only can read the x86 and C++ DLL so we need the unmanaged exports to worked as the middleware.
the example on 2 link is worked but for the string we should do the extra work. because the MQL4 encoding the string in UTF-16 or UCS-2. so you should convert the string in utf-16 code on DLL.
the final code for C# DLL and change the code too this is:

C#
using RGiesecke.DllExport;
using System.Runtime.InteropServices;
using System.Management;
using System;

namespace SystemInformationMQL4
{
    public class Class1
    {
        [DllExport("GetMotherboardSerialNumber", CallingConvention = CallingConvention.StdCall)]
        public static IntPtr GetMotherboardSerialNumber()
        {
            string serialNumber = string.Empty;
            using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_BaseBoard"))
            {
                foreach (var queryObj in searcher.Get())
                {
                    serialNumber = queryObj["SerialNumber"].ToString();
                    break; // only need the first result
                }
            }
            return Marshal.StringToHGlobalUni(serialNumber);
        }

        [DllExport("GetStorageDeviceSerialNumber", CallingConvention = CallingConvention.StdCall)]
        public static IntPtr GetStorageDeviceSerialNumber()
        {
            string serialNumber = string.Empty;
            using (var searcher = new ManagementObjectSearcher("SELECT SerialNumber FROM Win32_DiskDrive WHERE MediaType='Fixed hard disk media'"))
            {
                foreach (var queryObj in searcher.Get())
                {
                    serialNumber = queryObj["SerialNumber"].ToString();
                    break; // only need the first result
                }
            }
            return Marshal.StringToHGlobalUni(serialNumber);
        }
    }
}


and the mql4 code is:

MQL4
#import "SystemInformationMQL4.dll"
string GetMotherboardSerialNumber();
string GetStorageDeviceSerialNumber();

#import

int OnInit()
  {

   string motherBoard = GetMotherboardSerialNumber();
   string hardDrive = GetStorageDeviceSerialNumber();
   
   
   Alert(motherBoard + " " + hardDrive);
 return(INIT_SUCCEEDED);
  }

and with this we have C# DLL worked in MQL4.
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900