diff --git a/Common/Context.h b/Common/Context.h
index e08c318c3fe4bb60818e3229c2f859e9dc7e7e56..7647532ecf352596d9aa487a21efb4a90ab36cb6 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -259,7 +259,8 @@ class CTX {
     int plugins, listen;
     double timeout;
     std::string socketName, pythonInterpreter, octaveInterpreter;
-    std::string name[NUM_SOLVERS], executable[NUM_SOLVERS], remoteLogin[NUM_SOLVERS];
+    std::string name[NUM_SOLVERS], extension[NUM_SOLVERS];
+    std::string executable[NUM_SOLVERS], remoteLogin[NUM_SOLVERS];
     int autoSaveDatabase, autoArchiveOutputFiles, autoMesh, autoMergeFile;
     int autoShowViews, autoShowLastStep, autoCheck, showInvisibleParameters;
   }solver;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 6c5153898494f6bab87ad8a8e3382fa8a4ebc5df..06c9936ff49d6ddd4cf3f4c33b98b01f3c44dbfd 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -189,6 +189,27 @@ StringXString SolverOptions_String[] = {
   { F|S, "Name9" , opt_solver_name9 , "" ,
     "Name of solver 9" },
 
+  { F|S, "Extension0" , opt_solver_extension0 , ".pro" ,
+    "File extension for solver 0" },
+  { F|S, "Extension1" , opt_solver_extension1 , "" ,
+    "File extension for solver 1" },
+  { F|S, "Extension2" , opt_solver_extension2 , "" ,
+    "File extension for solver 2" },
+  { F|S, "Extension3" , opt_solver_extension3 , "" ,
+    "File extension for solver 3" },
+  { F|S, "Extension4" , opt_solver_extension4 , "" ,
+    "File extension for solver 4" },
+  { F|S, "Extension5" , opt_solver_extension5 , "" ,
+    "File extension for solver 5" },
+  { F|S, "Extension6" , opt_solver_extension6 , "" ,
+    "File extension for solver 6" },
+  { F|S, "Extension7" , opt_solver_extension7 , "" ,
+    "File extension for solver 7" },
+  { F|S, "Extension8" , opt_solver_extension8 , "" ,
+    "File extension for solver 8" },
+  { F|S, "Extension9" , opt_solver_extension9 , "" ,
+    "File extension for solver 9" },
+
   { F|S, "OctaveInterpreter" , opt_solver_octave_interpreter , "octave" ,
     "Name of the Octave interpreter (used to run .m files)" },
   { F|S, "PythonInterpreter" , opt_solver_python_interpreter , "python" ,
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 711daa5d2b77e398f3c1a026479ad6d926fcd144..cdbe0a1a71f00e9f02faaed1dac8ec48433371e8 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -276,6 +276,15 @@ void ParseString(const std::string &str, bool inCurrentModelDir)
   }
 }
 
+static std::string getSolverForExtension(const std::string &ext)
+{
+  for(int i = 0; i < NUM_SOLVERS; i++){
+    if(opt_solver_extension(i, GMSH_GET, "") == ext)
+      return opt_solver_name(i, GMSH_GET, "");
+  }
+  return "";
+}
+
 static int defineSolver(const std::string &name)
 {
   for(int i = 0; i < NUM_SOLVERS; i++){
@@ -343,6 +352,28 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setWindowTit
 #endif
 
   int status = 0;
+#if defined(HAVE_ONELAB)
+  std::string solver = getSolverForExtension(ext);
+  if(solver.size()){
+    int num = defineSolver(solver);
+    GModel::current()->setName(split[1] + ".geo");
+    GModel::current()->setFileName(split[0] + split[1] + ".geo");
+    CTX::instance()->launchSolverAtStartup = num;
+    CTX::instance()->solverToRun = num; // used in ONELAB2
+    return 1;
+
+  }
+  else if(ext == ".py" || ext == ".PY" ||
+          ext == ".m" || ext == ".M" ||
+          ext == ".exe" || ext == ".EXE"){
+    int num = defineSolver(split[1]);
+    opt_solver_executable(num, GMSH_SET, fileName);
+    CTX::instance()->launchSolverAtStartup = num;
+    CTX::instance()->solverToRun = num; // used in ONELAB2
+    return 1;
+  }
+  else
+#endif
   if(ext == ".stl" || ext == ".STL"){
     status = GModel::current()->readSTL(fileName, CTX::instance()->geom.tolerance);
   }
@@ -433,33 +464,6 @@ int MergeFile(const std::string &fileName, bool warnIfMissing, bool setWindowTit
   else if(ext == ".csv"){
     status = readFile3M(fileName);
   }
-#endif
-#if defined(HAVE_ONELAB)
-  else if(ext == ".pro" || ext == ".PRO"){
-    int num = defineSolver("GetDP");
-    GModel::current()->setName(split[1] + ".geo");
-    GModel::current()->setFileName(split[0] + split[1] + ".geo");
-    CTX::instance()->launchSolverAtStartup = num;
-    CTX::instance()->solverToRun = num; // used in ONELAB2
-    return 1;
-  }
-  else if(ext == ".vnek" || ext == ".VNEK"){
-    int num = defineSolver("vNek.exe");
-    GModel::current()->setName(split[1] + ".vnek");
-    GModel::current()->setFileName(split[0] + split[1] + ".vnek");
-    CTX::instance()->launchSolverAtStartup = num;
-    CTX::instance()->solverToRun = num; // used in ONELAB2
-    return 1;
-  }
-  else if(ext == ".py" || ext == ".PY" ||
-          ext == ".m" || ext == ".M" ||
-          ext == ".exe" || ext == ".EXE"){
-    int num = defineSolver(split[1]);
-    opt_solver_executable(num, GMSH_SET, fileName);
-    CTX::instance()->launchSolverAtStartup = num;
-    CTX::instance()->solverToRun = num; // used in ONELAB2
-    return 1;
-  }
 #endif
   else {
     CTX::instance()->geom.draw = 1;
diff --git a/Common/Options.cpp b/Common/Options.cpp
index e54d7756b9fee72a16f5d41df29137725d148c83..ff2cafc5d4768118d7f1ace98cc48b57ca103b69 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1433,6 +1433,64 @@ std::string opt_solver_name9(OPT_ARGS_STR)
   return opt_solver_name(9, action, val);
 }
 
+std::string opt_solver_extension(OPT_ARGS_STR)
+{
+  if(num < 0 || num > NUM_SOLVERS - 1) return "";
+  if(action & GMSH_SET)
+    CTX::instance()->solver.extension[num] = val;
+  return CTX::instance()->solver.extension[num];
+}
+
+std::string opt_solver_extension0(OPT_ARGS_STR)
+{
+  return opt_solver_extension(0, action, val);
+}
+
+std::string opt_solver_extension1(OPT_ARGS_STR)
+{
+  return opt_solver_extension(1, action, val);
+}
+
+std::string opt_solver_extension2(OPT_ARGS_STR)
+{
+  return opt_solver_extension(2, action, val);
+}
+
+std::string opt_solver_extension3(OPT_ARGS_STR)
+{
+  return opt_solver_extension(3, action, val);
+}
+
+std::string opt_solver_extension4(OPT_ARGS_STR)
+{
+  return opt_solver_extension(4, action, val);
+}
+
+std::string opt_solver_extension5(OPT_ARGS_STR)
+{
+  return opt_solver_extension(5, action, val);
+}
+
+std::string opt_solver_extension6(OPT_ARGS_STR)
+{
+  return opt_solver_extension(6, action, val);
+}
+
+std::string opt_solver_extension7(OPT_ARGS_STR)
+{
+  return opt_solver_extension(7, action, val);
+}
+
+std::string opt_solver_extension8(OPT_ARGS_STR)
+{
+  return opt_solver_extension(8, action, val);
+}
+
+std::string opt_solver_extension9(OPT_ARGS_STR)
+{
+  return opt_solver_extension(9, action, val);
+}
+
 std::string opt_solver_executable(OPT_ARGS_STR)
 {
   if(num < 0 || num > NUM_SOLVERS - 1) return "";
diff --git a/Common/Options.h b/Common/Options.h
index 6d85ca161cf18c615024bcb4d823a50014a98691..71afb1ac843ce364613c4d7dc00de26ea8a54e9b 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -74,6 +74,17 @@ std::string opt_solver_name6(OPT_ARGS_STR);
 std::string opt_solver_name7(OPT_ARGS_STR);
 std::string opt_solver_name8(OPT_ARGS_STR);
 std::string opt_solver_name9(OPT_ARGS_STR);
+std::string opt_solver_extension(OPT_ARGS_STR);
+std::string opt_solver_extension0(OPT_ARGS_STR);
+std::string opt_solver_extension1(OPT_ARGS_STR);
+std::string opt_solver_extension2(OPT_ARGS_STR);
+std::string opt_solver_extension3(OPT_ARGS_STR);
+std::string opt_solver_extension4(OPT_ARGS_STR);
+std::string opt_solver_extension5(OPT_ARGS_STR);
+std::string opt_solver_extension6(OPT_ARGS_STR);
+std::string opt_solver_extension7(OPT_ARGS_STR);
+std::string opt_solver_extension8(OPT_ARGS_STR);
+std::string opt_solver_extension9(OPT_ARGS_STR);
 std::string opt_solver_executable(OPT_ARGS_STR);
 std::string opt_solver_executable0(OPT_ARGS_STR);
 std::string opt_solver_executable1(OPT_ARGS_STR);