Fix maintenancetool writing in Windows

In Windows, maintenancetool is written using vb script. Installer
assumed that extension .vbs is always executed with script engine which
is not always true. In such cases create own extension (.qtInstaller)
which can be run with script engine

Task-number: QTIFW-1096
Change-Id: Ic52427e778fc7f3a540256e16b9e67b728c70d41
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
This commit is contained in:
Katja Marttila 2018-09-28 13:07:47 +03:00
parent 0fce306236
commit 9d7cff74d9

View File

@ -141,39 +141,49 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
{
#ifdef Q_OS_WIN
QStringList arguments;
{
QTemporaryFile f(QDir::temp().absoluteFilePath(QLatin1String("deferredrenameXXXXXX.vbs")));
QInstaller::openForWrite(&f);
f.setAutoRemove(false);
arguments << QDir::toNativeSeparators(f.fileName()) << QDir::toNativeSeparators(oldName)
<< QDir::toNativeSeparators(QFileInfo(oldName).dir().absoluteFilePath(QFileInfo(newName)
.fileName()));
QTextStream batch(&f);
batch.setCodec("UTF-16");
batch << "Set fso = WScript.CreateObject(\"Scripting.FileSystemObject\")\n";
batch << "Set tmp = WScript.CreateObject(\"WScript.Shell\")\n";
batch << QString::fromLatin1("file = \"%1\"\n").arg(arguments[2]);
batch << "on error resume next\n";
batch << "while fso.FileExists(file)\n";
batch << " fso.DeleteFile(file)\n";
batch << " WScript.Sleep(1000)\n";
batch << "wend\n";
batch << QString::fromLatin1("fso.MoveFile \"%1\", file\n").arg(arguments[1]);
if (restart) {
//Restart with same command line arguments as first executable
QStringList commandLineArguments = QCoreApplication::arguments();
batch << QString::fromLatin1("tmp.exec \"%1 --updater").arg(arguments[2]);
//Skip the first argument as that is executable itself
for (int i = 1; i < commandLineArguments.count(); i++) {
batch << QString::fromLatin1(" %1").arg(commandLineArguments.at(i));
}
batch << QString::fromLatin1("\"\n");
}
batch << "fso.DeleteFile(WScript.ScriptFullName)\n";
// Check if .vbs extension can be used for running renaming script. If not, create own extension
QString extension = QLatin1String(".vbs");
QSettingsWrapper settingRoot(QLatin1String("HKEY_CLASSES_ROOT\\.vbs"), QSettingsWrapper::NativeFormat);
if (settingRoot.value(QLatin1String(".")).toString() != QLatin1String("VBSFile")) {
extension = QLatin1String(".qtInstaller");
QSettingsWrapper settingsUser(QLatin1String("HKEY_CURRENT_USER\\Software\\Classes"), QSettingsWrapper::NativeFormat);
QString value = settingsUser.value(extension).toString();
if (value != QLatin1String("VBSFile"))
settingsUser.setValue(extension, QLatin1String("VBSFile"));
}
QTemporaryFile f(QDir::temp().absoluteFilePath(QLatin1String("deferredrenameXXXXXX%1")).arg(extension));
QInstaller::openForWrite(&f);
f.setAutoRemove(false);
arguments << QDir::toNativeSeparators(f.fileName()) << QDir::toNativeSeparators(oldName)
<< QDir::toNativeSeparators(QFileInfo(oldName).dir().absoluteFilePath(QFileInfo(newName)
.fileName()));
QTextStream batch(&f);
batch.setCodec("UTF-16");
batch << "Set fso = WScript.CreateObject(\"Scripting.FileSystemObject\")\n";
batch << "Set tmp = WScript.CreateObject(\"WScript.Shell\")\n";
batch << QString::fromLatin1("file = \"%1\"\n").arg(arguments[2]);
batch << "on error resume next\n";
batch << "while fso.FileExists(file)\n";
batch << " fso.DeleteFile(file)\n";
batch << " WScript.Sleep(1000)\n";
batch << "wend\n";
batch << QString::fromLatin1("fso.MoveFile \"%1\", file\n").arg(arguments[1]);
if (restart) {
//Restart with same command line arguments as first executable
QStringList commandLineArguments = QCoreApplication::arguments();
batch << QString::fromLatin1("tmp.exec \"%1 --updater").arg(arguments[2]);
//Skip the first argument as that is executable itself
for (int i = 1; i < commandLineArguments.count(); i++) {
batch << QString::fromLatin1(" %1").arg(commandLineArguments.at(i));
}
batch << QString::fromLatin1("\"\n");
}
batch << "fso.DeleteFile(WScript.ScriptFullName)\n";
QProcessWrapper::startDetached(QLatin1String("cscript"), QStringList() << QLatin1String("//Nologo")
<< arguments[0]);