 src/corelibs/U2Core/U2Core.pro                     |  2 ++
 .../U2Core/src/tasks/ExternalToolRunTask.cpp       | 16 ++++++---
 .../U2Core/src/tasks/ExternalToolRunTask.h         |  2 +-
 .../U2Core/src/util/CoreExternalToolsUtils.cpp     | 39 ++++++++++++++++++++
 .../U2Core/src/util/CoreExternalToolsUtils.h       | 42 ++++++++++++++++++++++
 src/corelibs/U2Lang/src/support/WorkflowUtils.cpp  |  4 ---
 src/corelibs/U2Lang/src/support/WorkflowUtils.h    |  2 --
 src/include/U2Core/CoreExternalToolsUtils.h        |  1 +
 .../src/utils/ExternalToolValidateTask.cpp         | 23 ++++++------
 .../src/library/ExternalProcessWorker.cpp          |  4 +--
 10 files changed, 110 insertions(+), 25 deletions(-)

diff --git a/src/corelibs/U2Core/U2Core.pro b/src/corelibs/U2Core/U2Core.pro
index 275c267f0..ba3377259 100644
--- a/src/corelibs/U2Core/U2Core.pro
+++ b/src/corelibs/U2Core/U2Core.pro
@@ -217,6 +217,7 @@ HEADERS += src/cmdline/CMDLineCoreOptions.h \
            src/util/AnnotationCreationPattern.h \
            src/util/AssemblyImporter.h \
            src/util/ChromatogramUtils.h \
+           src/util/CoreExternalToolsUtils.h \
            src/util/DatatypeSerializeUtils.h \
            src/util/FileAndDirectoryUtils.h \
            src/util/FilesIterator.h \
@@ -443,6 +444,7 @@ SOURCES += src/cmdline/CMDLineCoreOptions.cpp \
            src/util/AnnotationCreationPattern.cpp \
            src/util/AssemblyImporter.cpp \
            src/util/ChromatogramUtils.cpp \
+           src/util/CoreExternalToolsUtils.cpp \
            src/util/DatatypeSerializeUtils.cpp \
            src/util/FileAndDirectoryUtils.cpp \
            src/util/FilesIterator.cpp \
diff --git a/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.cpp b/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.cpp
index d143b4c52..9da25b16e 100644
--- a/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.cpp
+++ b/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.cpp
@@ -25,6 +25,7 @@
 #include <U2Core/AppContext.h>
 #include <U2Core/AppSettings.h>
 #include <U2Core/CmdlineTaskRunner.h>
+#include <U2Core/CoreExternalToolsUtils.h>
 #include <U2Core/ExternalToolRegistry.h>
 #include <U2Core/GUrlUtils.h>
 #include <U2Core/Log.h>
@@ -376,12 +377,20 @@ void ExternalToolSupportUtils::appendExistingFile(const QString &path, QStringLi
     }
 }
 
-bool ExternalToolSupportUtils::startExternalProcess(QProcess *process, const QString &program, const QStringList &arguments) {
+bool ExternalToolSupportUtils::startExternalProcess(QProcess *process, const QString &program, const QStringList &arguments, bool tryLaunchWithCmd) {
     process->start(program, arguments);
     bool started = process->waitForStarted(START_WAIT_MSEC);
-
-#ifdef Q_OS_WIN32
     if (!started) {
+        QStringList extendedArgs(arguments);
+        QString execFileName = CoreExternalToolsUtils::detectLauncherExeByExtension(program);
+        if (execFileName.isEmpty()) {
+            extendedArgs.prepend(execFileName);
+            process->start(execFileName, extendedArgs);
+            started = process->waitForStarted(START_WAIT_MSEC);
+        }
+    }
+#ifdef Q_OS_WIN
+    if (!started && tryLaunchWithCmd) {
         QString execStr = WIN_LAUNCH_CMD_COMMAND + program;
         foreach(const QString arg, arguments) {
             execStr += " " + arg;
@@ -392,7 +401,6 @@ bool ExternalToolSupportUtils::startExternalProcess(QProcess *process, const QSt
         started = process->waitForStarted(START_WAIT_MSEC);
     }
 #endif
-
     return started;
 }
 
diff --git a/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.h b/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.h
index 37450f294..a37760406 100644
--- a/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.h
+++ b/src/corelibs/U2Core/src/tasks/ExternalToolRunTask.h
@@ -139,7 +139,7 @@ public:
      */
     static QString createTmpDir(const QString &prePath, const QString &domain, U2OpStatus &os);
     static void appendExistingFile(const QString &path, QStringList &files);
-    static bool startExternalProcess(QProcess *process, const QString &program, const QStringList &arguments);
+    static bool startExternalProcess(QProcess *process, const QString &program, const QStringList &arguments, bool tryLaunchWithCmd = true);
     static ProcessRun prepareProcess(const QString &toolName, const QStringList &arguments, const QString &workingDirectory, const QStringList &additionalPaths, U2OpStatus &os, ExternalToolListener* listener);
     static QString prepareArgumentsForCmdLine(const QStringList &arguments);
     static QStringList splitCmdLineArguments(const QString &execString);
diff --git a/src/corelibs/U2Core/src/util/CoreExternalToolsUtils.cpp b/src/corelibs/U2Core/src/util/CoreExternalToolsUtils.cpp
new file mode 100644
index 000000000..a8cdebe7d
--- /dev/null
+++ b/src/corelibs/U2Core/src/util/CoreExternalToolsUtils.cpp
@@ -0,0 +1,39 @@
+/**
+ * UGENE - Integrated Bioinformatics Tools.
+ * Copyright (C) 2008-2019 UniPro <ugene@unipro.ru>
+ * http://ugene.net
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "CoreExternalToolsUtils.h"
+
+#include <QFileInfo>
+#include <QStandardPaths>
+
+namespace U2 {
+
+const QMap<QString, QString> CoreExternalToolsUtils::extToExeFileMap = { {"py", "python"}, {"pl", "perl"} };
+
+const QString& CoreExternalToolsUtils::detectLauncherExeByExtension(const QString& toolPath) {
+    QFileInfo path(toolPath);
+    if (extToExeFileMap[path.suffix()].isEmpty()) {
+        return "";
+    }
+    return QStandardPaths::findExecutable(extToExeFileMap[path.suffix()]);
+}
+
+}
\ No newline at end of file
diff --git a/src/corelibs/U2Core/src/util/CoreExternalToolsUtils.h b/src/corelibs/U2Core/src/util/CoreExternalToolsUtils.h
new file mode 100644
index 000000000..72e902a80
--- /dev/null
+++ b/src/corelibs/U2Core/src/util/CoreExternalToolsUtils.h
@@ -0,0 +1,42 @@
+/**
+ * UGENE - Integrated Bioinformatics Tools.
+ * Copyright (C) 2008-2019 UniPro <ugene@unipro.ru>
+ * http://ugene.net
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef _U2_CORE_EXTERNAL_TOOLS_UTILS_H_
+#define _U2_CORE_EXTERNAL_TOOLS_UTILS_H_
+
+#include <QString>
+#include <QMap>
+
+#include <U2Core/global.h>
+
+namespace U2 {
+
+class U2CORE_EXPORT CoreExternalToolsUtils {
+public:
+    static const QString& detectLauncherExeByExtension(const QString& toolPath);
+
+private:
+    static const QMap<QString, QString> extToExeFileMap;
+};
+
+}
+
+#endif
diff --git a/src/corelibs/U2Lang/src/support/WorkflowUtils.cpp b/src/corelibs/U2Lang/src/support/WorkflowUtils.cpp
index 3a4cd26fb..d91d5ce4f 100644
--- a/src/corelibs/U2Lang/src/support/WorkflowUtils.cpp
+++ b/src/corelibs/U2Lang/src/support/WorkflowUtils.cpp
@@ -752,10 +752,6 @@ void WorkflowUtils::applyPathsToBusMap(StrStrMap &busMap, const SlotPathMap &pat
     }
 }
 
-bool WorkflowUtils::startExternalProcess(QProcess *process, const QString &program, const QStringList &arguments) {
-    return ExternalToolSupportUtils::startExternalProcess(process, program, arguments);
-}
-
 QStringList WorkflowUtils::getDatasetsUrls(const QList<Dataset> &sets) {
     QStringList result;
     foreach (const Dataset &dSet, sets) {
diff --git a/src/corelibs/U2Lang/src/support/WorkflowUtils.h b/src/corelibs/U2Lang/src/support/WorkflowUtils.h
index cc2c5b660..a507ccf18 100644
--- a/src/corelibs/U2Lang/src/support/WorkflowUtils.h
+++ b/src/corelibs/U2Lang/src/support/WorkflowUtils.h
@@ -99,8 +99,6 @@ public:
 
     static void applyPathsToBusMap(StrStrMap &busMap, const SlotPathMap &pathMap);
 
-    static bool startExternalProcess(QProcess *process, const QString &program, const QStringList &arguments);
-
     static QStringList getDatasetsUrls(const QList<Dataset> &sets);
 
     static QStringList getAttributeUrls(Attribute *attr);
diff --git a/src/include/U2Core/CoreExternalToolsUtils.h b/src/include/U2Core/CoreExternalToolsUtils.h
new file mode 100644
index 000000000..8630be4c9
--- /dev/null
+++ b/src/include/U2Core/CoreExternalToolsUtils.h
@@ -0,0 +1 @@
+#include "../../corelibs/U2Core/src/util/CoreExternalToolsUtils.h"
diff --git a/src/plugins/external_tool_support/src/utils/ExternalToolValidateTask.cpp b/src/plugins/external_tool_support/src/utils/ExternalToolValidateTask.cpp
index 22ed64143..1a2493846 100644
--- a/src/plugins/external_tool_support/src/utils/ExternalToolValidateTask.cpp
+++ b/src/plugins/external_tool_support/src/utils/ExternalToolValidateTask.cpp
@@ -19,12 +19,15 @@
  * MA 02110-1301, USA.
  */
 
+#include <QStandardPaths>
 #include <QString>
 
 #include <U2Core/AppContext.h>
 #include <U2Core/AppResources.h>
 #include <U2Core/CmdlineTaskRunner.h>
+#include <U2Core/CoreExternalToolsUtils.h>
 #include <U2Core/ExternalToolRegistry.h>
+#include <U2Core/ExternalToolRunTask.h>
 #include <U2Core/Log.h>
 #include <U2Core/ScriptingToolRegistry.h>
 #include <U2Core/U2SafePoints.h>
@@ -87,7 +90,7 @@ void ExternalToolJustValidateTask::run() {
                                .arg(toolName));
         } else {
             originalValidation.arguments.prepend(originalValidation.executableFile);
-            for (int i = stool->getRunParameters().size() - 1; i >= 0; i--){
+            for (int i = stool->getRunParameters().size() - 1; i >= 0; i--) {
                 originalValidation.arguments.prepend(stool->getRunParameters().at(i));
             }
             originalValidation.executableFile = stool->getPath();
@@ -117,26 +120,22 @@ void ExternalToolJustValidateTask::run() {
         externalToolProcess = new QProcess();
         setEnvironment(tool);
 
-        externalToolProcess->start(validation.executableFile, validation.arguments);
-        bool started = externalToolProcess->waitForStarted(3000);
-
-        if (!started) {
+        if (!ExternalToolSupportUtils::startExternalProcess(externalToolProcess, validation.executableFile, validation.arguments, false)) {
             errorMsg = validation.possibleErrorsDescr.value(ExternalToolValidation::DEFAULT_DESCR_KEY, "");
             if (!errorMsg.isEmpty()) {
                 stateInfo.setError(errorMsg);
             } else {
                 stateInfo.setError(tr("Tool does not start.<br>"
-                                      "It is possible that the specified executable file "
-                                      "<i>%1</i> for %2 tool is invalid. You can change "
-                                      "the path to the executable file in the external "
-                                      "tool settings in the global preferences.")
-                                   .arg(toolPath)
-                                   .arg(toolName));
+                    "It is possible that the specified executable file "
+                    "<i>%1</i> for %2 tool is invalid. You can change "
+                    "the path to the executable file in the external "
+                    "tool settings in the global preferences.")
+                    .arg(toolPath)
+                    .arg(toolName));
             }
             isValid = false;
             return;
         }
-
         int elapsedTime = 0;
         const int timeout = tool->isCustom() ? 0 : TIMEOUT_MS;      // Custom tools can't be validated properly now, there is no need to wait them
         while (!externalToolProcess->waitForFinished(CHECK_PERIOD_MS)) {
diff --git a/src/plugins/workflow_designer/src/library/ExternalProcessWorker.cpp b/src/plugins/workflow_designer/src/library/ExternalProcessWorker.cpp
index 841386641..da77cab04 100644
--- a/src/plugins/workflow_designer/src/library/ExternalProcessWorker.cpp
+++ b/src/plugins/workflow_designer/src/library/ExternalProcessWorker.cpp
@@ -692,8 +692,8 @@ void LaunchExternalToolTask::run() {
     QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
     externalProcess->setProcessEnvironment(env);
     taskLog.details(tr("Running external process: %1").arg(execString));
-    bool startOk = WorkflowUtils::startExternalProcess(externalProcess, execStringProg, execStringArgs);
-
+    bool startOk = ExternalToolSupportUtils::startExternalProcess(externalProcess, execStringProg, execStringArgs);
+    
     if(!startOk) {
         stateInfo.setError(tr("Can't launch %1").arg(execString));
         return;
