diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
index f24962b01d..d1bda27c31 100644
--- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
+++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
@@ -2307,7 +2307,9 @@ int main(int argc, char *argv[])
// ~~~~~~~~~~~~~~~~
// (replacement for setRootCase that does not abort)
- Foam::argList args(argc, argv);
+ argList args(argc, argv);
+ #include "foamDlOpenLibs.H"
+
const bool reconstruct = args.found("reconstruct");
const bool writeCellDist = args.found("cellDist");
const bool dryrun = args.found("dry-run");
diff --git a/applications/utilities/preProcessing/mapFields/mapFields.C b/applications/utilities/preProcessing/mapFields/mapFields.C
index f7d399a603..249cfc3d3b 100644
--- a/applications/utilities/preProcessing/mapFields/mapFields.C
+++ b/applications/utilities/preProcessing/mapFields/mapFields.C
@@ -276,11 +276,11 @@ int main(int argc, char *argv[])
argList args(argc, argv);
-
if (!args.check())
{
FatalError.exit();
}
+ #include "foamDlOpenLibs.H"
fileName rootDirTarget(args.rootPath());
fileName caseDirTarget(args.globalCaseName());
diff --git a/applications/utilities/preProcessing/mapFieldsPar/mapFieldsPar.C b/applications/utilities/preProcessing/mapFieldsPar/mapFieldsPar.C
index 4b580f6a87..13494ace9e 100644
--- a/applications/utilities/preProcessing/mapFieldsPar/mapFieldsPar.C
+++ b/applications/utilities/preProcessing/mapFieldsPar/mapFieldsPar.C
@@ -208,6 +208,7 @@ int main(int argc, char *argv[])
);
argList args(argc, argv);
+ #include "foamDlOpenLibs.H"
fileName rootDirTarget(args.rootPath());
fileName caseDirTarget(args.globalCaseName());
diff --git a/src/OpenFOAM/include/foamDlOpenLibs.H b/src/OpenFOAM/include/foamDlOpenLibs.H
new file mode 100644
index 0000000000..27ee219943
--- /dev/null
+++ b/src/OpenFOAM/include/foamDlOpenLibs.H
@@ -0,0 +1,12 @@
+// Force dlOpen of FOAM_DLOPEN_LIBS,
+// which is a comma-separated list of quoted library names
+// (eg, "finiteVolume","fvOptions","meshTools")
+//
+// Principally for Windows applications where library loading may otherwise
+// be incomplete.
+
+#ifdef FOAM_DLOPEN_LIBS
+
+Foam::dlOpen({ FOAM_DLOPEN_LIBS }, false); // Silent on errors
+
+#endif
diff --git a/src/OpenFOAM/include/setRootCase.H b/src/OpenFOAM/include/setRootCase.H
index 6205697d95..e90a7410c6 100644
--- a/src/OpenFOAM/include/setRootCase.H
+++ b/src/OpenFOAM/include/setRootCase.H
@@ -15,3 +15,6 @@ if (!args.checkRootCase())
// {
// Foam::FatalError.exit();
// }
+
+// Force dlOpen of FOAM_DLOPEN_LIBS (principally for Windows applications)
+#include "foamDlOpenLibs.H"
diff --git a/wmake/makefiles/files b/wmake/makefiles/files
index 52a0b2db56..fb825976c9 100644
--- a/wmake/makefiles/files
+++ b/wmake/makefiles/files
@@ -35,6 +35,12 @@ SFILES = $(OBJECTS_DIR)/sourceFiles
sinclude $(OPTIONS)
+#------------------------------------------------------------------------------
+# Directory containing the wmake scripts
+#------------------------------------------------------------------------------
+
+WM_SCRIPTS = $(WM_DIR)/scripts
+
#------------------------------------------------------------------------------
# Declare dependency of all make system files on FILES
@@ -45,7 +51,9 @@ all : $(OPTIONS) $(SFILES) $(VARS)
$(OPTIONS) : $(MAKE_DIR)/options
@$(CPP) $(GFLAGS) $(MAKE_DIR)/options | sed -e 's@ *@ @g' > $(OPTIONS)
-
+ifeq ("$(WM_OSTYPE)","MSwindows")
+ @$(WM_SCRIPTS)/wmakeWindowsDlOpenLibs $(OPTIONS) >> $(OPTIONS)
+endif
$(SFILES): $(MAKE_DIR)/files
@$(CPP) $(GFLAGS) $(MAKE_DIR)/files | sed -e 's@ *@ @g' > $(FILES)
diff --git a/wmake/scripts/wmakeWindowsDlOpenLibs b/wmake/scripts/wmakeWindowsDlOpenLibs
new file mode 100755
index 0000000000..44074a80ba
--- /dev/null
+++ b/wmake/scripts/wmakeWindowsDlOpenLibs
@@ -0,0 +1,101 @@
+#!/bin/sh
+#------------------------------------------------------------------------------
+# ========= |
+# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+# \\ / O peration |
+# \\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
+# \\/ M anipulation |
+#-------------------------------------------------------------------------------
+# | Copyright (C) 2011-2017 blueCAPE Lda
+#------------------------------------------------------------------------------
+# License
+# This file is part of OpenFOAM.
+#
+# OpenFOAM 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 3 of the License, or
+# (at your option) any later version.
+#
+# OpenFOAM 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 OpenFOAM. If not, see .
+#
+# Script
+# wmakeWindowsDlOpenLibs
+#
+# Usage
+# wmakeWindowsDlOpenLibs
+#
+# Description
+# Extract library dependencies from the EXE_LIBS entry for Windows
+# applications and emit as FOAM_DLOPEN_LIBS for use with setRootCase.H
+# Forcibly dlOpen'ing these libraries ensures that they are truly loaded
+# for the windows application binary.
+#
+# An alternative means is to define external entry points into particular
+# libraries and linking with '-u symbol', which would possibly have a lower
+# overhead but is more code-intrusive and somewhat ad hoc.
+#
+#------------------------------------------------------------------------------
+optionsFile="$1"
+
+[ "$#" -gt 0 ] || exit 1
+[ -f "$optionsFile" ] || exit 2
+[ -r "$optionsFile" ] || exit 2
+
+# Representative exeName from the build path (for messages only)
+# Eg, build/.../basic/laplacianFoam/options -> laplacianFoam
+
+exeName="${optionsFile%/options}" # Strip trailing '/options'
+exeName="${exeName##*/}" # Strip leading path
+
+# Use only OpenFOAM-related libraries that we will can actually find
+hasLib()
+{
+ libFile="lib${1}.dll" # NB: Windows only (.dll)
+
+ [ -e "$FOAM_LIBBIN/$libFile" ] || \
+ [ -e "$FOAM_USER_LIBBIN/$libFile" ] || \
+ [ -e "$FOAM_LIBBIN/$FOAM_MPI/$libFile" ]
+}
+
+
+# After the cpp stage, the EXE_LIBS (if they exist) will be on a single line
+# Extract EXE_LIBS = -labc ..., ignoring -L and .o entries
+#
+# The libNames output comprises comma-separated quoted strings
+# "lib1","lib2","libN"
+# these are suitable for C-code or a std::initializer_list etc.
+
+# The $() sub-shell is unquoted to ensure we get whitespace splitting
+# and read individual words, not lines.
+unset libNames
+for lib in $(sed -ne 's@^.*EXE\_LIBS.*=[ ]*@@p' "$optionsFile")
+do
+ case "$lib" in
+ (*.o | *')'*)
+ ;;
+
+ (-l[0-9A-Za-z]*)
+ lib="${lib#-l}"
+ hasLib "$lib" && libNames="$libNames${libNames:+,}\"$lib\""
+ ;;
+ esac
+done
+
+## Debugging: echo "$exeName: libNames=$libNames" 1>&2
+
+# Emit define for using with Foam::dlOpen()
+if [ -n "$libNames" ]
+then
+ echo "Adding dlOpen(dll) list for $exeName" 1>&2
+ echo "EXE_INC += -DFOAM_DLOPEN_LIBS='$libNames'"
+fi
+
+exit 0 # clean exit
+
+#------------------------------------------------------------------------------