Download MetaTrader 5
To add comments, please log in or register
Need mobile version of MetaTrader 5? Download it and trade!
xuzhe 2014.06.10 12:40 

i want my mt4 program communicate with C# codes in different kinds of computers,X86 and 64bits

so i decide to try Named Pipe,a solution without any DLL

here's my mql4 code:

#include <Files\FilePipe.mqh>

CFilePipe ExtPipe;

int OnInit()
//--- create timer
   bool bfirst=true;
         Print("Client: waiting for pipe server");
   Print("Client: pipe opened");
   //--- send welcome message
   if(!ExtPipe.WriteString(__FILE__+" on MQL4 build "+IntegerToString(__MQL4BUILD__)))
      Print("Client: sending welcome message failed");
   Print("Welcome message sended");
   //--- read data from server
   string str;
   int    value=0;

   Print("Trying to recv");
      Print("Client: reading string failed");
   Print("Server: \"",str,"\" received");

 copy from example code

send welcome info to server and wait one sec,waiting server messages.

and my C# code:


public static NamedPipeServerStream pipeServer = new NamedPipeServerStream("My.Pipe.Server", PipeDirection.InOut);

        static void Main(string[] args)
            Console.WriteLine("Named pipe server stream object created");
            Console.WriteLine("Waiting for client connection...:");

            Thread thRead = new Thread(new ThreadStart(OnConnected));

        private static void OnConnected()
            while (true)

                    Console.WriteLine("Client connected");

                    byte[] byteRec;
                    byteRec = new byte[256];

                    pipeServer.Read(byteRec, 0, 256);

                    List<byte> listWeNeed = new List<byte>();
                    foreach (byte b in byteRec)
                        if (b != '\0')

                    byte[] byteFinally = listWeNeed.ToArray();

                    string strReaded = Encoding.UTF8.GetString(byteFinally);

                    if (strReaded.Length > 2)
                        //Send some message to mt4

                        if (pipeServer.CanWrite)
                            byte[] write = Encoding.UTF8.GetBytes("42");

                            pipeServer.Write(write, 0, write.Length);

                catch (IOException e)
                    Console.WriteLine("ERROR {0}", e.Message);
xuzhe 2014.06.10 12:45  

the mt4 shows the welcome message sended,and it is true:

the c# side:


the c# received "PipeTest.mq4 on MQL4 build 553" which mt4 sended.

but when i order C# to send a message by the code


pipeServer.Write(write, 0, write.Length);

it does not work.

pipeServer.Write method always doesn't work.


Do anybody know WHY?


Thanks a lot. 

Carl Schreiber
Carl Schreiber 2014.06.10 17:16  

Hi, I do have similar troubles with the Metatrader Named Pipe :(

I wrote a little PowerShell Pipeserver - PowerShell should be related:

# is the comment sign like // in Metatrader
$BaseName = "testpipe"
$Enc = [System.Text.Encoding]::UTF8 # ASCII # 
$Buf = new-object byte[] 4096

function ReadMsg ($r, $e, $b) {
    try {
        $got = ""
        $Loops = 0
        Write-Host "start ReadMsg.."
        do {
            # Read what data is available
            $foundmore = $false
            do {
                try {
                    $read = $r.Read($b, 0, $b.Length)
                    Write-Host "READ: $read  Result: $($read.Result)"
                    if($read -gt 0) {
                        $foundmore = $true
                        #$got += $e.GetString($b, 0, $read)
                        #$got += [char]$($b | where{$_ -gt 0})
                        foreach ($x in $b) { 
                            if ($x -gt 0){$got += [char]$x; Write-Host "$x => $got" }
                            #else { Write-Host "$b"}
                        $nTry = -1
                        Write-Host "rdMsg: rd:$read, $got" 
                } catch { $foundMore = $false; $read = 0; }
            } while($read -gt 0)
            if ($nTry -gt 0) {Start-Sleep -m 5; $nTry--;}
        } while($foundmore -or $nTry -gt 0)
    finally { 
        return $got 

function rdPipe ($r, $e, $b) {
    $ret = ""
    $n = 0
    Do {
      $b = $r.Read()
      if ($b -gt 0 ) {
          $c = [char]$b #
          $ret += $c
          Write-Host "rdMsg $n: $ret" 
    } while( $b -gt 0 -and $c -ne $EOS )
    if ($ret -ne "" ) { Write-Host "FINAL b $b,  n: $n, ret: $ret" }
    return $ret

$pipeDir  = [System.IO.Pipes.PipeDirection]::InOut
$pipeMsg  = [System.IO.Pipes.PipeTransmissionMode]::Message
$pipeOpti = [System.IO.Pipes.PipeOptions]::Asynchronous
$pipe = New-Object system.IO.Pipes.NamedPipeServerStream( $pipeName, $pipeDir, 1, $pipeMsg, $pipeOpti )
if ( !$pipe.IsConnected ) { $pipe.WaitForConnection() }
echo "Connected Pipe: $pipeName"
$pw = new-object System.IO.StreamWriter $pipe
$pw.AutoFlush = $true
$pr = new-object System.IO.StreamReader $pipe

$mSec = 100
while ( $pipe.IsConnected ) {
    $got = rdPipe $pr $sw $Enc $Buf "P:S" # ($read, $wrt, $enc, $buf, $direction) ReadMsg
    #$got = rdPipe $pipe $sw $Enc $Buf "P:S" # ($read, $wrt, $enc, $buf, $direction) ReadMsg
    #$got = ReadMsg $pr $sw $Enc $Buf "P:S" # ($read, $wrt, $enc, $buf, $direction) ReadMsg
    if ( $got -ne "" ) {
        echo "P:S^^ $got"
        if ( $got -match "_EXIT_" ) { break }
        else {
            $found = $got -match "Sleep_mSec:(\d+)"
            if ($found) { 
                $mSec = $MATCHES[1] 
                echo "chg Sleeping to $mSec mSec"
    Start-Sleep -m $mSec    
if ( $pipe.IsConnected ) {

My welcome-message is just "Hi, I am your client :)". But either I don't receive it: the buffer $b is always 0 or with rdPipe-Function I read the message but the server is blocked it cant leave the loop Do {..} while() until the MT4-script closes the socket.

I have no idea what to do ?? I tried to change between ANSI and UNICODE on MT4-side and ASCII and UTF8 in the PS-script no change - anybody here with an enlightening idea?

I really would appreciate it.

Thanks in advance,


Carl Schreiber
Carl Schreiber 2014.06.12 09:56  

C# has the same problem - I guess - as PowerShell. In the c++ PipeServer it is defined to read only a specific number of bytes but neither C# nor PowerShell provides this.

Both can read the stream and will hang unless the socket is closed by the client.

xuzhe 2014.06.13 09:01  

i found a way to communicate between MT4 and C#


i create a file in \MQL4\Files Folder,and i use FILE_SHARE_READ|FILE_SHARE_WRITE to make this file can be share by other programs.

in C# side,i just write messages to this file,and MQL4 read.


NamePipe is also a kind of file sharing i made it by myself. 

xuzhe 2014.06.13 09:05  

C# has the same problem - I guess - as PowerShell. In the c++ PipeServer it is defined to read only a specific number of bytes but neither C# nor PowerShell provides this.

Both can read the stream and will hang unless the socket is closed by the client.

i wrote such C# codes to find the file path


string strAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

StringBuilder sbTerminalPath = new StringBuilder(strAppDataPath);

string strTerminalPath = sbTerminalPath.ToString();

var SubDirectories = Directory.GetDirectories(strTerminalPath).ToList<string>();

foreach (string strDir in SubDirectories)
    StringBuilder sbFileDir = new StringBuilder(strDir);

    string strFileDir = sbFileDir.ToString();
    if (Directory.Exists(strFileDir))

       StringBuilder sbNewsFile = new StringBuilder(strFileDir);

       string strNewsFile = sbNewsFile.ToString();
       if (!File.Exists(strNewsFile))
       //strNewsFile is the path we need
bikitha 2015.03.02 08:31  

You can use socket programming to connect.....C# Socket Programming


To add comments, please log in or register