We've all tried it. There's something we want to do in a DLL but Metatrader is still stuck in the 19th century. For my inquiry, I give you this:
The EA:
using (StreamWriter writer = new StreamWriter(@"ClientMessage.txt", true))
{
writer.WriteLine(line);
}
}
}
}
Run that and get this:
Unhandled exception 0xE0434352
So, anyone got any ideas?
Your file ClientMessage.txt is potentially going to be written into the working directory of the MT4 executable. This can be the \Program Files area, and attempts to write there will fail unless the MT4 executable is running with escalated privileges.
So, you may simply have an unhandled .NET exception arising from a file access error. Try explicitly writing ClientMessage.txt to an unprotected area of disk.
I do not know this language, but is the "using" keyword in the WriteMe method OK?
Your file ClientMessage.txt is potentially going to be written into the working directory of the MT4 executable. This can be the \Program Files area, and attempts to write there will fail unless the MT4 executable is running with escalated privileges.
So, you may simply have an unhandled .NET exception arising from a file access error. Try explicitly writing ClientMessage.txt to an unprotected area of disk.
However I don't have enough experience with DLL, what's the difference with using a WINAPI DLL to write anywhere outside MT4 sandbox ?
No difference. The issue with the C# code appears to be that it's not specifying a location for the ClientMessage.txt file, and therefore it may be defaulting to the startup/working directory of terminal.exe. If that's within Program Files, then attempts to write the file will fail.
Ok. It's not where the DLL writes the file. The '@' symbol specifies to write the file where the DLL was launched from. In this case, the MQL/Libraries folder. I've changed this to my documents / downloads / etc. Doesn't matter.
It's the using statement. Metatrader bombs on that statement. Why? Has anyone gotten a using statement to work in a C# DLL for Metatrader? I thought this worked in previous builds.
(Yes. It's simply telling .NET to dispose of the object at the end of the Using block, closing the file handle. I believe it's equivalent to java.io.Closeable: http://stackoverflow.com/a/2016311)
Ok. It's not where the DLL writes the file. The '@' symbol specifies to write the file where the DLL was launched from. In this case, the MQL/Libraries folder. I've changed this to my documents / downloads / etc. Doesn't matter.
It's the using statement. Metatrader bombs on that statement. Why? Has anyone gotten a using statement to work in a C# DLL for Metatrader? I thought this worked in previous builds.
As far as I am aware, the @ simply indicates a verbatim string literal. It is not going to control where the file is written.
Your code works for me in a copy of MT4 installed outside \Program Files, and crashes if MT4 is installed inside \Program Files.
If I run MT4 from a location such as C:\MyMT4, i.e. such that the executable is C:\MyMT4\terminal.exe, then the file ClientMessage.txt is created at C:\MyMT4\ClientMessage.txt. This is obviously going to cause problems if MT4 is inside a protected area of disk such as \Program Files.
If I change your code as follows ...
{
try
{
using (StreamWriter writer = new StreamWriter(@"ClientMessage.txt", true))
{
writer.WriteLine(line);
}
}
catch (Exception e)
{
System.Diagnostics.Trace.WriteLine(e.Message);
}
}
... then the exception which is logged when I use the DLL from a copy of MT4 within Program Files is, very unsurprisingly, as follows:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
We've all tried it. There's something we want to do in a DLL but Metatrader is still stuck in the 19th century. For my inquiry, I give you this:
The EA:
//| MT4Exports.mq4 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#import "MT4Exports.dll"
int addthem(int a, int b);
int addthemO(int a, int b);
#import
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
int result=addthem(3,5);
Print("result:",result);
result=addthemO(4,6);
Print("result:",result);
}
//+------------------------------------------------------------------+
The DLL
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RGiesecke.DllExport;
using System.IO;
namespace MT4Exports
{
public class Class1
{
[DllExport]
public static int addthem(int a, int b)
{
WriteMe("Running addthem");
return a + b;
}
[DllExport]
public static int addthemO(int a, int b)
{
return FigureO.addthem(a, b);
}
public static void WriteMe(string line)
{
using (StreamWriter writer = new StreamWriter(@"ClientMessage.txt", true))
{
writer.WriteLine(line);
}
}
}
public class FigureO
{
public static int addthem(int a, int b)
{
return a + b;
}
}
}
Run that and get this:
Unhandled exception 0xE0434352
Change the DLL to this:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RGiesecke.DllExport;
using System.IO;
namespace MT4Exports
{
public class Class1
{
[DllExport]
public static int addthem(int a, int b)
{
//WriteMe("Running addthem");
return a + b;
}
[DllExport]
public static int addthemO(int a, int b)
{
return FigureO.addthem(a, b);
}
/*
public static void WriteMe(string line)
{
using (StreamWriter writer = new StreamWriter(@"ClientMessage.txt", true))
{
writer.WriteLine(line);
}
}
*/
}
public class FigureO
{
public static int addthem(int a, int b)
{
return a + b;
}
}
}
..And it works flawlessly.
So the question is, why? Is this something I'm doing wrong? I don't think so.
So, anyone got any ideas?