diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp
index fe70597c7346207a20019ba413ea8f30f6d2a301..dbee326954d661a8f0da89a3f7bb049cf51c59ea 100644
--- a/src/windeployqt/main.cpp
+++ b/src/windeployqt/main.cpp
@@ -247,6 +247,10 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
                                     QStringLiteral("Force updating files."));
     parser->addOption(forceOption);
 
+    QCommandLineOption dryRunOption(QStringLiteral("dry-run"),
+                                    QStringLiteral("Simulation mode. Behave normally, but do not copy/update any files."));
+    parser->addOption(dryRunOption);
+
     QCommandLineOption noPluginsOption(QStringLiteral("no-plugins"),
                                        QStringLiteral("Skip plugin deployment."));
     parser->addOption(noPluginsOption);
@@ -339,6 +343,8 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
     options->quickImports = !parser->isSet(noQuickImportOption);
     if (parser->isSet(forceOption))
         options->updateFileFlags |= ForceUpdateFile;
+    if (parser->isSet(dryRunOption))
+        options->updateFileFlags |= SkipUpdateFile;
 
     for (size_t i = 0; i < qtModulesCount; ++i) {
         if (parser->isSet(*enabledModules.at(int(i)).first.data()))
@@ -626,7 +632,7 @@ static QStringList translationNameFilters(unsigned modules, const QString &prefi
 }
 
 static bool deployTranslations(const QString &sourcePath, unsigned usedQtModules,
-                               const QString &target, QString *errorMessage)
+                               const QString &target, unsigned flags, QString *errorMessage)
 {
     // Find available languages prefixes by checking on qtbase.
     QStringList prefixes;
@@ -656,8 +662,10 @@ static bool deployTranslations(const QString &sourcePath, unsigned usedQtModules
         if (optVerboseLevel)
             std::printf("Creating %s...\n", qPrintable(targetFile));
         unsigned long exitCode;
-        if (!runProcess(binary, arguments, sourcePath, &exitCode, 0, 0, errorMessage) || exitCode)
+        if (!(flags & SkipUpdateFile)
+            && (!runProcess(binary, arguments, sourcePath, &exitCode, 0, 0, errorMessage) || exitCode)) {
             return false;
+        }
     } // for prefixes.
     return true;
 }
@@ -890,7 +898,7 @@ static DeployResult deploy(const Options &options,
             if (!dir.exists(targetDirName)) {
                 if (optVerboseLevel)
                     std::printf("Creating directory %s.\n", qPrintable(targetDirName));
-                if (!dir.mkdir(targetDirName)) {
+                if (!(options.updateFileFlags & SkipUpdateFile) && !dir.mkdir(targetDirName)) {
                     std::fprintf(stderr, "Cannot create %s.\n",  qPrintable(targetDirName));
                     *errorMessage = QStringLiteral("Cannot create ") + targetDirName +  QLatin1Char('.');
                     return result;
@@ -935,7 +943,8 @@ static DeployResult deploy(const Options &options,
 
     if (options.translations
         && !deployTranslations(qmakeVariables.value(QStringLiteral("QT_INSTALL_TRANSLATIONS")),
-                               result.deployedQtLibraries, options.directory, errorMessage)) {
+                               result.deployedQtLibraries, options.directory,
+                               options.updateFileFlags, errorMessage)) {
         return result;
     }
 
diff --git a/src/windeployqt/utils.cpp b/src/windeployqt/utils.cpp
index 527a6e9d04fa5681137b5b4d3195fb0838d64e29..68c78d76e8544974b11a00ba745756cffd11a9fa 100644
--- a/src/windeployqt/utils.cpp
+++ b/src/windeployqt/utils.cpp
@@ -510,7 +510,7 @@ QString queryQMake(const QString &variable, QString *errorMessage)
 
 // Update a file or directory.
 bool updateFile(const QString &sourceFileName, const QStringList &nameFilters,
-                const QString &targetDirectory, JsonOutput *json, QString *errorMessage)
+                const QString &targetDirectory, unsigned flags, JsonOutput *json, QString *errorMessage)
 {
     const QFileInfo sourceFileInfo(sourceFileName);
     const QString targetFileName = targetDirectory + QLatin1Char('/') + sourceFileInfo.fileName();
@@ -541,7 +541,7 @@ bool updateFile(const QString &sourceFileName, const QStringList &nameFilters,
             QDir d(targetDirectory);
             if (optVerboseLevel)
                 std::printf("Creating %s.\n", qPrintable( QDir::toNativeSeparators(targetFileName)));
-            if (!d.mkdir(sourceFileInfo.fileName())) {
+            if (!(flags & SkipUpdateFile) && !d.mkdir(sourceFileInfo.fileName())) {
                 *errorMessage = QString::fromLatin1("Cannot create directory %1 under %2.")
                                 .arg(sourceFileInfo.fileName(), QDir::toNativeSeparators(targetDirectory));
                 return false;
@@ -551,13 +551,14 @@ bool updateFile(const QString &sourceFileName, const QStringList &nameFilters,
         QDir dir(sourceFileName);
         const QStringList allEntries = dir.entryList(nameFilters, QDir::Files) + dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
         foreach (const QString &entry, allEntries)
-            if (!updateFile(sourceFileName + QLatin1Char('/') + entry, nameFilters, targetFileName, json, errorMessage))
+            if (!updateFile(sourceFileName + QLatin1Char('/') + entry, nameFilters, targetFileName, flags, json, errorMessage))
                 return false;
         return true;
     } // Source is directory.
 
     if (targetFileInfo.exists()) {
-        if (targetFileInfo.lastModified() >= sourceFileInfo.lastModified()) {
+        if (!(flags & ForceUpdateFile)
+            && targetFileInfo.lastModified() >= sourceFileInfo.lastModified()) {
             if (optVerboseLevel)
                 std::printf("%s is up to date.\n", qPrintable(sourceFileInfo.fileName()));
             if (json)
@@ -565,7 +566,7 @@ bool updateFile(const QString &sourceFileName, const QStringList &nameFilters,
             return true;
         }
         QFile targetFile(targetFileName);
-        if (!targetFile.remove()) {
+        if (!(flags & SkipUpdateFile) && !targetFile.remove()) {
             *errorMessage = QString::fromLatin1("Cannot remove existing file %1: %2")
                             .arg(QDir::toNativeSeparators(targetFileName), targetFile.errorString());
             return false;
@@ -574,7 +575,7 @@ bool updateFile(const QString &sourceFileName, const QStringList &nameFilters,
     QFile file(sourceFileName);
     if (optVerboseLevel)
         std::printf("Updating %s.\n", qPrintable(sourceFileInfo.fileName()));
-    if (!file.copy(targetFileName)) {
+    if (!(flags & SkipUpdateFile) && !file.copy(targetFileName)) {
         *errorMessage = QString::fromLatin1("Cannot copy %1 to %2: %3")
                 .arg(QDir::toNativeSeparators(sourceFileName),
                      QDir::toNativeSeparators(targetFileName),
diff --git a/src/windeployqt/utils.h b/src/windeployqt/utils.h
index fc09a34c72aad8fd3ae794b5c628881110b1673b..b9aa99d9fc4835a8cdd979e7d86bb634301244a4 100644
--- a/src/windeployqt/utils.h
+++ b/src/windeployqt/utils.h
@@ -149,7 +149,7 @@ QString queryQMake(const QString &variable, QString *errorMessage);
 QStringList findSharedLibraries(const QDir &directory, Platform platform, bool debug, const QString &prefix = QString());
 
 bool updateFile(const QString &sourceFileName, const QStringList &nameFilters,
-                const QString &targetDirectory, JsonOutput *json, QString *errorMessage);
+                const QString &targetDirectory, unsigned flags, JsonOutput *json, QString *errorMessage);
 bool runProcess(const QString &binary, const QStringList &args,
                 const QString &workingDirectory = QString(),
                 unsigned long *exitCode = 0, QByteArray *stdOut = 0, QByteArray *stdErr = 0,
@@ -187,7 +187,8 @@ extern int optVerboseLevel;
 // Recursively update a file or directory, matching DirectoryFileEntryFunction against the QDir
 // to obtain the files.
 enum UpdateFileFlag  {
-    ForceUpdateFile = 0x1
+    ForceUpdateFile = 0x1,
+    SkipUpdateFile = 0x2
 };
 
 template <class DirectoryFileEntryFunction>
@@ -233,7 +234,7 @@ bool updateFile(const QString &sourceFileName,
             if (relativeSource == relativeTarget) // Exists and points to same entry: happy.
                 return true;
             QFile existingTargetFile(targetFileName);
-            if (!existingTargetFile.remove()) {
+            if (!(flags & SkipUpdateFile) && !existingTargetFile.remove()) {
                 *errorMessage = QString::fromLatin1("Cannot remove existing symbolic link %1: %2")
                                 .arg(QDir::toNativeSeparators(targetFileName), existingTargetFile.errorString());
                 return false;
@@ -253,7 +254,7 @@ bool updateFile(const QString &sourceFileName,
             QDir d(targetDirectory);
             if (optVerboseLevel)
                 std::printf("Creating %s.\n", qPrintable(targetFileName));
-            if (!d.mkdir(sourceFileInfo.fileName())) {
+            if (!(flags & SkipUpdateFile) && !d.mkdir(sourceFileInfo.fileName())) {
                 *errorMessage = QString::fromLatin1("Cannot create directory %1 under %2.")
                                 .arg(sourceFileInfo.fileName(), QDir::toNativeSeparators(targetDirectory));
                 return false;
@@ -279,7 +280,7 @@ bool updateFile(const QString &sourceFileName,
             return true;
         }
         QFile targetFile(targetFileName);
-        if (!targetFile.remove()) {
+        if (!(flags & SkipUpdateFile) && !targetFile.remove()) {
             *errorMessage = QString::fromLatin1("Cannot remove existing file %1: %2")
                             .arg(QDir::toNativeSeparators(targetFileName), targetFile.errorString());
             return false;
@@ -288,7 +289,7 @@ bool updateFile(const QString &sourceFileName,
     QFile file(sourceFileName);
     if (optVerboseLevel)
         std::printf("Updating %s.\n", qPrintable(sourceFileInfo.fileName()));
-    if (!file.copy(targetFileName)) {
+    if (!(flags & SkipUpdateFile) && !file.copy(targetFileName)) {
         *errorMessage = QString::fromLatin1("Cannot copy %1 to %2: %3")
                 .arg(QDir::toNativeSeparators(sourceFileName),
                      QDir::toNativeSeparators(targetFileName),