<# .SYNOPSIS Minimal reproduction of MetaEditor bug: /include makes #resource report error 313 (invalid resource path). .DESCRIPTION Generates a single 2-line .mq5 that only includes the official Canvas/Canvas3D.mqh (which internally references Shaders\*.hlsl via #resource in Include\Canvas\DX\DXDispatcher.mqh). Then compiles the same file twice: A) without /include -> compiles cleanly (0 errors) B) with /include -> reports error 313 (invalid resource path) even though the resource files exist under Include\Canvas\DX\Shaders\. Conclusion: the /include switch breaks #resource relative-path resolution. Generated file: \MQL5\Experts\ReproResource.mq5 .EXAMPLE .\MetaEditorResource313Repro.ps1 -TerminalDir "F:\soft\MetaTrader5EXNESS" .EXAMPLE .\MetaEditorResource313Repro.ps1 # detect or prompt for the terminal dir .PARAMETER TerminalDir Terminal install directory (the folder that contains metaeditor64.exe and MQL5). When omitted, the script first checks the InstallDirs list below and otherwise prompts for it interactively. .PARAMETER MetaEditor Full path to metaeditor64.exe / metaeditor.exe. Auto-detected when omitted. .PARAMETER Cleanup Remove the generated files (mq5/ex5) after the test. #> param( [string]$TerminalDir = "", [string]$MetaEditor = "", [switch]$Cleanup ) $ErrorActionPreference = "Stop" [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false) # Candidate terminal install directories (edit for your machine). $InstallDirs = @( "F:\soft\MetaTrader5EXNESS" # "D:\soft\MetaTrader 5" # "E:\software\MetaTrader4EXNESS2" # "D:\soft\MetaTrader4EXNESS" ) function Get-ExistingPath { param([string]$Path) if ([string]::IsNullOrWhiteSpace($Path)) { return "" } if (-not (Test-Path -LiteralPath $Path)) { return "" } return (Get-Item -LiteralPath $Path).FullName } function Find-InstallDir { # Prefer a directory that has a usable MQL5 tree (Include + Experts). foreach ($d in $InstallDirs) { $p = Get-ExistingPath $d if ($p -and (Test-Path -LiteralPath (Join-Path $p "MQL5\Include")) -and (Test-Path -LiteralPath (Join-Path $p "MQL5\Experts"))) { return $p } } foreach ($d in $InstallDirs) { $p = Get-ExistingPath $d if ($p) { return $p } } return "" } function Find-MetaEditorIn { param([string]$Dir) foreach ($name in @("metaeditor64.exe", "metaeditor.exe")) { $p = Join-Path $Dir $name $r = Get-ExistingPath $p if ($r) { return $r } } return "" } # ---------- 1. Resolve terminal dir and MetaEditor ---------- if ([string]::IsNullOrWhiteSpace($TerminalDir)) { $TerminalDir = Find-InstallDir } if ([string]::IsNullOrWhiteSpace($TerminalDir)) { $answer = Read-Host "Enter terminal install directory (e.g. F:\soft\MetaTrader5EXNESS)" $TerminalDir = Get-ExistingPath $answer } if ([string]::IsNullOrWhiteSpace($TerminalDir)) { Write-Error "Terminal install directory not found. Pass -TerminalDir or edit the InstallDirs list." exit 2 } $mqlRoot = Join-Path $TerminalDir "MQL5" if (-not (Test-Path -LiteralPath (Join-Path $mqlRoot "Include\Canvas\Canvas3D.mqh")) -or -not (Test-Path -LiteralPath (Join-Path $mqlRoot "Experts"))) { Write-Error "No usable MQL5 tree (Canvas\Canvas3D.mqh missing): $mqlRoot" exit 2 } if ([string]::IsNullOrWhiteSpace($MetaEditor)) { $MetaEditor = Find-MetaEditorIn $TerminalDir } $MetaEditor = Get-ExistingPath $MetaEditor if ([string]::IsNullOrWhiteSpace($MetaEditor)) { Write-Error "MetaEditor not found. Pass -MetaEditor with the full path." exit 2 } # ---------- 2. Generate the minimal repro .mq5 ---------- $srcMq5 = Join-Path (Join-Path $mqlRoot "Experts") "ReproResource.mq5" $mq5Lines = @( "#include ", "void OnInit() {", "", "}" ) Set-Content -LiteralPath $srcMq5 -Value $mq5Lines -Encoding UTF8 Write-Host "TerminalDir : $TerminalDir" Write-Host "MQL5 root : $mqlRoot" Write-Host "MetaEditor : $MetaEditor" Write-Host "Source file : $srcMq5" Write-Host "" # ---------- 3. Compile A: without /include ---------- $logBase = Join-Path $env:TEMP "MT5ResourceRepro" New-Item -ItemType Directory -Force -Path $logBase | Out-Null $logA = Join-Path $logBase "compile_no_include.log" $logB = Join-Path $logBase "compile_with_include.log" Remove-Item -LiteralPath $logA, $logB -ErrorAction SilentlyContinue $null = Start-Process -FilePath $MetaEditor ` -ArgumentList "/compile:`"$srcMq5`"", "/log:`"$logA`"", "/fast" ` -Wait -PassThru # ---------- 4. Compile B: with /include ---------- $null = Start-Process -FilePath $MetaEditor ` -ArgumentList "/compile:`"$srcMq5`"", "/include:`"$mqlRoot`"", "/log:`"$logB`"", "/fast" ` -Wait -PassThru Write-Host "===== A) without /include =====" if (Test-Path -LiteralPath $logA) { Get-Content -LiteralPath $logA -Encoding UTF8 | Select-Object -Last 5 } else { Write-Host "(no log generated)" } Write-Host "" Write-Host "===== B) with /include =====" if (Test-Path -LiteralPath $logB) { Get-Content -LiteralPath $logB -Encoding UTF8 | Select-Object -Last 5 } else { Write-Host "(no log generated)" } Write-Host "" $lastA = if (Test-Path -LiteralPath $logA) { (Get-Content -LiteralPath $logA -Encoding UTF8 | Select-Object -Last 1) } else { "(no log)" } $lastB = if (Test-Path -LiteralPath $logB) { (Get-Content -LiteralPath $logB -Encoding UTF8 | Select-Object -Last 1) } else { "(no log)" } Write-Host "===== Result =====" Write-Host "A) without /include : $lastA (expected 0 errors)" Write-Host "B) with /include : $lastB (reproduces error 313)" Write-Host "" # ---------- 5. Optional cleanup ---------- if ($Cleanup) { Remove-Item -LiteralPath $srcMq5, (Join-Path (Join-Path $mqlRoot "Experts") "ReproResource.ex5") -Force -ErrorAction SilentlyContinue Write-Host "Generated repro files removed." }