Uploaded image for project: 'Qt Installer Framework'
  1. Qt Installer Framework
  2. QTIFW-175

"Normalize" installation path on Windows in installer

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 1.3.0
    • 1.2
    • General
    • None
    • aff8a9920257d25d6f2651c909ce277ddbd75c59

    Description

      QML does extra checks on Windows to make sure any path passed in is correctly capitalized. The installer does not yet take this into account, and e.g. installs the application happily to C:\qt\... even if there's a C:\Qt\... on the file system.

      This has side effects for the installer:

      • Qt Creator will be launched with wrong directory, and e.g. the welcome screen stays blank
      • the binary QtQuick1/QtQuick examples get the 'wrong' path patched in, and do not launch any more

      Easiest fix (apart from removing this stupid QtDeclarative/QtQml file case check) is to let the installer 'normalize' the path it uses right in the beginning. Qt Creator has following code to normalize paths:

      QTCREATOR_UTILS_EXPORT QString getShortPathName(const QString &name)
      {
          if (name.isEmpty())
              return name;
      
          // Determine length, then convert.
          const LPCTSTR nameC = reinterpret_cast<LPCTSTR>(name.utf16()); // MinGW
          const DWORD length = GetShortPathNameW(nameC, NULL, 0);
          if (length == 0)
              return name;
          QScopedArrayPointer<TCHAR> buffer(new TCHAR[length]);
          GetShortPathNameW(nameC, buffer.data(), length);
          const QString rc = QString::fromUtf16(reinterpret_cast<const ushort *>(buffer.data()), length - 1);
          return rc;
      }
      
      QTCREATOR_UTILS_EXPORT QString getLongPathName(const QString &name)
      {
          if (name.isEmpty())
              return name;
      
          // Determine length, then convert.
          const LPCTSTR nameC = reinterpret_cast<LPCTSTR>(name.utf16()); // MinGW
          const DWORD length = GetLongPathNameW(nameC, NULL, 0);
          if (length == 0)
              return name;
          QScopedArrayPointer<TCHAR> buffer(new TCHAR[length]);
          GetLongPathNameW(nameC, buffer.data(), length);
          const QString rc = QString::fromUtf16(reinterpret_cast<const ushort *>(buffer.data()), length - 1);
          return rc;
      }
      
      // makes sure that capitalization of directories is canonical.
      // This mimics the logic in QDeclarative_isFileCaseCorrect
      QTCREATOR_UTILS_EXPORT QString normalizePathName(const QString &name)
      {
          QString canonicalName = getShortPathName(name);
          if (canonicalName.isEmpty())
              return name;
          canonicalName = getLongPathName(canonicalName);
          if (canonicalName.isEmpty())
              return name;
          // Upper case drive letter
          if (canonicalName.size() > 2 && canonicalName.at(1) == QLatin1Char(':'))
              canonicalName[0] = canonicalName.at(0).toUpper();
          return canonicalName;
      }
      

      Attachments

        Issue Links

          Activity

            People

              heimrich Karsten Heimrich
              kkohne Kai Köhne
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: