AM2
Андрей

 
Уровень 34

  Торгую в компаниях:


Группа "Программирование на MQL"

Рейтинг 280



Создание символьных ссылок в системе Windows

Совсем недавно я столкнулся с одной неприятной особенностью при работе с файлами в MetaTrader 4. Мое самописное приложение обменивается данными с экспертом через текстовый файл. Советник может читать файл только в «песочнице» т.е. из папок MetaTrader 4. Раньше в старых билдах можно было прочитать файл с помощью функций Win Api из kernel32.dll.


#import "kernel32.dll"
   ...
#import



//+------------------------------------------------------------------+
//|   прочитать файл и вернуть строку с содержимым                   |
//+------------------------------------------------------------------+
string ReadFile (string path) 
  {
    int handle=_lopen (path,OF_READ);           
    if(handle<0) 
      {
        Print("Ошибка открытия файла ",path); 
        return ("");
      }
    int result=_llseek (handle,0,0);      
    if(result<0) 
      {
        Print("Ошибка установки указателя" ); 
        return ("");
      }
    string buffer="";
    string char1="x";
    int count=0;
    result=_lread (handle,char1,1);
    while(result>0) 
      {
        buffer=buffer+char1;
        char1="x";
        count++;
        result=_lread (handle,char1,1);
     }
    result=_lclose (handle);              
    if(result<0)  
      Print("Ошибка закрытия файла ",path);
    return (buffer);
  }
 


Также и сейчас это можно сделать таким образом:


#define OF_EXIST   0x00004000
#define OFS_MAXPATHNAME 128

struct OFSTRUCT
{
  uchar cBytes;
  uchar fFixedDisk;
  ushort nErrCode;
  ushort Reserved1;
  ushort Reserved2;
  uchar szPathName[OFS_MAXPATHNAME];
};

#import "kernel32.dll"
   int OpenFile( string lpFileName, OFSTRUCT& lpReOpenBuff, int wStyle );
#import

void OnStart()
{
   int h = 0;
   OFSTRUCT ofstruct;
   h = OpenFile( "C:\\log.txt", ofstruct, OF_EXIST );
   Print( "Handle: ", h );
}


Но есть более простой и доступный способ и для тех кто не знаком с программированием Win Api функций — это символьные ссылки.
Чтобы продемонстрировать работу с симлинками я написал простой скрипт на MQL4:


//+------------------------------------------------------------------+
//|                                                     ReadFile.mq4 |
//|                                              Copyright 2015, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, AM2"
#property link      "http://www.forexsystems.biz"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int h=FileOpen("C:\\log.txt",FILE_READ|FILE_TXT);
   Print("Handle: ",h);
  }
//+------------------------------------------------------------------+



Скрипт бросается на график и если файл прочитан, то пишет в журнал сообщение:

ReadFile AUDUSD,H1: Handle: 1


Т.к. функция FileOpen видит только файлы в песочнице, то в на вкладке Эксперты мы увидим следующую запись:

2015.09.06 12:35:41.258 ReadText AUDUSD,H1: Handle: -1



Для того чтобы скрипт видел диск С, выполним следующие действия:

1. Открываем командную строку, для этого жмём Win+R и в открывшемся окне пишем cmd:



2. В открывшемся окне командной строки нам необходимо создать символьную ссылку на диск С:\. Делается это с помощью команды mklink.

Команда выглядит следующим образом:

MKLINK [[/D] | [/H] | [/J]] Ссылка Назначение
/D — Создание символической ссылки на каталог (по умолчанию создается на файл).
/H — Создание жесткой связи вместо символической ссылки.
/J — Создание соединения для каталога.
Ссылка — Имя новой символической ссылки.
Назначение — Путь, на который ссылается новая ссылка.


mklink /d «D:\Program Files\Alpari Limited MT4\MQL4\Files» «c:\»

Таким образом мы будем ссылаться на диск С:\ из папки метатрейдера.

Здесь D:\Program Files\Alpari Limited MT4\MQL4\Files — это создаваемый симлинк, а c:\ — путь, на который она указывает. Таким образом система будет обращаться к «песочнице» D:\Program Files\Alpari Limited MT4\MQL4\Files, а на самом деле файл буде лежать на диске С:\.

Также симлинки можно создавать с помощью небольших утилит. В сети имеется ряд программ для создания символических ссылок, воспользуемся одной из них.

Создание символьных ссылок с помощью утилиты «Link Shell Extension»

Скачать эту бесплатную утилиту можно отсюда: www.opentraders.ru/downloads/855

Link Shell Extension добавляет в контекстное меню правой кнопки мыши некоторые пункты, позволяя создавать симлинки привычным способом вроде «копировать/вставить» без необходимости запускать командную строку.

Скачиваем, устанавливаем и запускаем Link Shell Extension. Во время установки можно выбрать русский язык. Само окно программы нам не требуется, его можно сразу закрыть, если вам не нужно устанавливать дополнительные настройки.

Использовать утилиту просто. Выбираем папку, для которой нужна ссылка, и щелкаем по ней правой кнопкой мыши — в меню выбираем Запомнить источник ссылки.



После этого открываем папку, где нужно эту ссылку вставить, и также делаем клик правой кнопкой, теперь выбираем Поместить как — Символическую ссылку. Готово.



Сейчас у нас в «песочнице» появилась папка «Files».



Если зайти в эту папку, то мы там увидим наш файл с другого диска.



И после этих не сложных манипуляций, мы можем обращаться к нему так как будто он лежит у нас в папке метатрейдера.

Немного поправим код скрипта:


//+------------------------------------------------------------------+
//|                                                     ReadFile.mq4 |
//|                                              Copyright 2015, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, AM2"
#property link      "http://www.forexsystems.biz"
#property version   "1.00"
#property strict

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int h=FileOpen("Files\\log.txt",FILE_READ|FILE_TXT);
   Print("Handle: ",h);
  }
//+------------------------------------------------------------------+



И вот скрипт уже видит файл, лежащий за пределами «песочницы».



П.С. В статье были использованы следующие материалы:

Пример применения символьных ссылок в Windows 7
www.ithowto.ru/475-primer-primeneniya-simvolnyx-ssylok-v-windows-7.html

Как создать символьную ссылку на папку или файл в Windows
2notebook.net/content/articles/kak-sozdat-simvolnuyu-ssylku-v-windows

Как из советника читать файл на «C:\log.txt»?
forum.mql4.com/ru/69084
  • +3
  • Просмотров: 9968
  • 6 сентября 2015, 14:32
  • AM2
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Программирование на MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
Как написать DLL для советника на MQL4
04 сентября 2015
16 сентября 2015

Комментарии (2)

+
+1
Отлично! :)  6 часов лазил по интернету для решения данного вопроса *wall* 
Проверил — работает! *lalala* 
И еще вот ссылка на установку программы под x64 системы Windows: http://www.opentraders.ru/downloads/962/
avatar

  9  amyrgan145 Сообщений: 428 - Амыр

  • 6 декабря 2015, 21:01
+
0
что за фигня, символьная ссылка на текстовый файл в mql4 создалась но советник текстового файла не видит
avatar

  0  sergey_scherbakov Сообщений: 2

  • 2 января 2017, 23:31

Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий
Начать торговлю с Альпари