Qt5widgets.dll error when it is installed to another computer

Asked

Viewed 538 times

3

I’m trying to export an application built in Qt 5.7.0 (compiled to 32 bits, although development takes place in a Windows 10 environment, 64 bits) to another computer (this one with Windows 8.1, 32 bits).

To do this, I have prepared the Cmake script to install all dependent Dlls (using the resource Bundleutilities which exists in the latest versions of Cmake). The script works as expected, copying the executable and the Dlls to the path set as the installation prefix.

However, when taking the generated file package to the target computer and trying to run the application there, the following error occurs:

inserir a descrição da imagem aqui

[...]\Qt5widgets.dll was not designed to run on Windows or contains an error. Try installing the program again using the media original installation or contact the system administrator or the software vendor to get support. Error status 0xc000035a.

Remarks:

  1. It should be possible to notice that the above test was done on a Windows 8.1, 32-bit, installed on a Vmware (used only for easy testing). But I already did the test also on the real machine and the error is the same (although on the real machine the operating system also complains of Qt5core.dll, and on Vmware it complains only of Qt5widgets.dll).

  2. The installed Qt is the 5.7.0, 32 bits, for Visual Studio 2015. I’ve checked and even reinstalled just to make sure I’m not using 64-bit binaries by mistake.

  3. When running on the development machine, the application works normally. And this machine has not no other version of Qt installed.

  4. Although the error occurs in a Qt DLL, I have already manually installed in Vmware the VS 2015 Redistributables (32 bits). But the error persists.

MCVE

Code file for the executable (teste.exe):

#include <QApplication>
#include <QLabel>

int main(int argc, char** argv)
{
    QApplication oApp(argc, argv);

    QLabel oLabel(0, Qt::Dialog);
    oLabel.setWindowFlags(oLabel.windowFlags() & ~Qt::WindowContextHelpButtonHint);
    oLabel.setWindowTitle("Teste para o SOPt");
    oLabel.setFixedSize(400, 150);

    oLabel.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    oLabel.setText("Olá Mundo!");
    oLabel.setStyleSheet("QLabel { font-size: 50px; color: black; background: white; } QLabel:hover { color: white; background: black; }");

    oLabel.show();
    return oApp.exec();
}

Cmake configuration file (CMakeLists.txt):

cmake_minimum_required(VERSION 2.8.11)
project(Teste)

#############################################
# Configuração
#############################################

# Tipos de build
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
endif()

# Configuração do Qt
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)

# Arquivos de código
file(GLOB SRC *.cpp *.h)

# Prepara o executável
if(WIN32)
    add_executable(Teste WIN32 ${SRC})
else()
    add_executable(Teste ${SRC})
endif()

# Configura nome do target
set_target_properties(Teste PROPERTIES OUTPUT_NAME teste)

# Configura libs linkadas
target_link_libraries(Teste Qt5::Core Qt5::Widgets)

#############################################
# Instalação
#############################################

# Instala o executável
install(TARGETS Teste DESTINATION bin)

# Instala as dependências do Qt
set(APP "\${CMAKE_INSTALL_PREFIX}/bin/teste.exe")
set(DIRS ${QT_LIBRARY_DIRS})
INSTALL(CODE "
   include(BundleUtilities)
   fixup_bundle(\"${APP}\"   \"\"   \"${DIRS}\")
   ")

# Instala outras dependências (VS 2015 Redistributable, etc)
include(InstallRequiredSystemLibraries)

After running Cmake, it will generate the Visual Studio solution. Then, after compiling the "Test" project (which generates the binary) and compiling the "Install" project (which copies the binary and dependency Dlls to the folder configured in the installation prefix - variable CMAKE_INSTALL_PREFIX), the folder configured for installation contains the following files:

inserir a descrição da imagem aqui

  • api-ms-win-crt-Environment-L1-1-0.dll
  • api-ms-win-crt-filesystem-L1-1-0.dll
  • api-ms-win-crt-heap-L1-1-0.dll
  • api-ms-win-crt-locale-L1-1-0.dll
  • api-ms-win-crt-Math-L1-1-0.dll
  • api-ms-win-crt-Runtime-L1-1-0.dll
  • api-ms-win-crt-stdio-L1-1-0.dll
  • api-ms-win-crt-string-L1-1-0.dll
  • api-ms-win-crt-time-L1-1-0.dll
  • api-ms-win-crt-Utility-L1-1-0.dll
  • msvcp140.dll
  • Qt5core.dll
  • Qt5gui.dll
  • Qt5widgets.dll
  • test.exe
  • vcruntime140.dll
  • 1

    Silly question... The Dlls used are those of deploy or debug?

  • @Bacco The question is not silly no. : ) Are the release. The project was compiled and copied in release (Qt Dlls that are debug have a letter "d" at the end of the name - for example: Qt5widgetsd.dll).

1 answer

3


Note: The final solution was given in the edition, added at the end of this reply.

I kind of figured out what happens. : / The error is in the copy made by BundleUtilities in the Cmake script (not that it’s wrong, maybe I’m the one who didn’t know how to use it correctly).

As the error complains that the binary image (in case the DLL) is inappropriate, I used the utility dumpbin (installed together with Visual Studio on the path C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\) and executed:

dumpbin Qt5Widgets.dll /headers

The result indicated that the image was, in fact, compiled to 64 bits (line marked with an arrow):

Microsoft (R) COFF/PE Dumper Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file Qt5Widgets.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
            8664 machine (x64) <==========================
               8 number of sections
        56F5814D time date stamp Fri Mar 25 15:19:57 2016
               0 file pointer to symbol table
               0 number of symbols
              F0 size of optional header
            2022 characteristics
                   Executable
                   Application can handle large (>2GB) addresses
                   DLL
[...]

But, as I said, I have confirmed that my installation of Qt is 32-bit. So I re-executed the installation inscript and paid attention to the output of Visual Studio:

1>------ Build started: Project: INSTALL, Configuration: Release Win32 ------
1>  -- Install configuration: "Release"
1>  -- Installing: C:/temp/Data/bin/teste.exe
1>  -- fixup_bundle
1>  --   app='C:/temp/Data/bin/teste.exe'
1>  --   libs=''
1>  --   dirs=''
1>  --   ignoreItems=''
1>  -- fixup_bundle: preparing...
1>  -- fixup_bundle: copying...
1>  -- 1/28: *NOT* copying 'C:/temp/Data/bin/teste.exe'
1>  -- 2/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/Qt5Core.dll'
1>  -- 3/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/Qt5Gui.dll'
1>  -- 4/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/Qt5Widgets.dll'
1>  -- 5/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-environment-l1-1-0.dll'
1>  -- 6/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-filesystem-l1-1-0.dll'
1>  -- 7/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-heap-l1-1-0.dll'
1>  -- 8/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-locale-l1-1-0.dll'
1>  -- 9/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-math-l1-1-0.dll'
1>  -- 10/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-runtime-l1-1-0.dll'
1>  -- 11/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-stdio-l1-1-0.dll'
1>  -- 12/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-string-l1-1-0.dll'
1>  -- 13/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-time-l1-1-0.dll'
1>  -- 14/28: copying 'C:/Program Files/MiKTeX 2.9/miktex/bin/x64/api-ms-win-crt-utility-l1-1-0.dll'
1>  -- fixup_bundle: fixing...
1>  -- 15/28: fix-up not required on this platform 'C:/temp/Data/bin/teste.exe'
1>  -- 16/28: fix-up not required on this platform 'C:/temp/Data/bin/Qt5Core.dll'
1>  -- 17/28: fix-up not required on this platform 'C:/temp/Data/bin/Qt5Gui.dll'
1>  -- 18/28: fix-up not required on this platform 'C:/temp/Data/bin/Qt5Widgets.dll'
1>  -- 19/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-environment-l1-1-0.dll'
1>  -- 20/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-filesystem-l1-1-0.dll'
1>  -- 21/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-heap-l1-1-0.dll'
1>  -- 22/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-locale-l1-1-0.dll'
1>  -- 23/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-math-l1-1-0.dll'
1>  -- 24/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-runtime-l1-1-0.dll'
1>  -- 25/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-stdio-l1-1-0.dll'
1>  -- 26/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-string-l1-1-0.dll'
1>  -- 27/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-time-l1-1-0.dll'
1>  -- 28/28: fix-up not required on this platform 'C:/temp/Data/bin/api-ms-win-crt-utility-l1-1-0.dll'
1>  -- fixup_bundle: cleaning up...
1>  -- fixup_bundle: verifying...
1>  -- ===========================================================================
1>  -- Analyzing app='C:/temp/Data/bin/teste.exe'
1>  -- bundle='C:/temp/Data/bin'
1>  -- executable='C:/temp/Data/bin/teste.exe'
1>  -- valid='1'
1>  -- executable file 1: C:/temp/Data/bin/teste.exe
1>  -- verified='1'
1>  -- info='Verified 1 executable files in 'C:/temp/Data/bin''
1>  --
1>  -- verified='1'
1>  -- info=''
1>  --
1>  -- fixup_bundle: done
1>  -- Installing: C:/temp/Data/bin/msvcp140.dll
1>  -- Installing: C:/temp/Data/bin/vcruntime140.dll
========== Build: 1 succeeded, 0 failed, 3 up-to-date, 0 skipped ==========

Yeah, so I had the displeasure to realize that Cmake was copying the dependencies from the wrong source: he’s copying from C:/Program Files/MiKTeX 2.9/miktex, which is an installation of Miktex (Latex compiler for Windows) which I have installed here (and which also uses Qt to develop its own graphical interfaces).

I will edit this answer again in the future. I’m still trying understand why he copied from the wrong source. My suspicion is that it searches the dependencies in the environment variable PATH and copies the first to find - despite of documentation say nothing to such respect (at least not clearly).

EDITING (Final Solution)

First, it occurs that the variable QT_LIBRARY_DIRS does not exist in Qt5. Apparently it existed in Qt4, but was unused in the new version since "targets" (like Qt5::Core) make it unnecessary to have access to the library directory directly (yet each "target" has its Cmake path set in the variable <target>_DIR). Thus, as this variable did not have the directory from which the BundleUtilities should take the Dlls, he simply followed some arbitrary order.

I tested by changing the order in the variable PATH, but nothing has changed (continued to pick up Miktex erroneously). After spending the whole day studying the problem, I came to the conclusion that the use of BundleUtilities does not help much. The way it finds the dependencies of an executable is unclear (from what I read in the documentation it uses itself dumpbin, among other tools), and even if I informed on a fixed basis (hardcoded) the directories from where he needed to get the dependencies, I discovered later that he simply ignored many of them.

For example, he did not copy the "plugin" qwidows.dll, and even forcing the copy of that file he did not copy it to the correct folder (./bin/platforms). He also did not copy some of the DLL’s C Runtime (that has changed in the version of Windows 10 and needs to be distributed - #Bummer).

Thus, I chose to copy the files manually same, in order to guarantee their origin without problems. The Cmake script below makes this copy without using BundleUtilities. I know that the ideal would be to identify automatically, but the directory from which to find the C Runtime Dlls needs to be configured and, for ease, I chose to simply send them all (even if only a few are being used in the code).

cmake_minimum_required(VERSION 2.8.11)
project(Teste)

#############################################
# Configuração
#############################################

# Tipos de build
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
endif()

# Configuração do Qt
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5 REQUIRED Core Widgets)

# Arquivos de código
file(GLOB SRC *.cpp *.h)

# Prepara o executável
if(WIN32)
    add_executable(Teste WIN32 ${SRC})
else()
    add_executable(Teste ${SRC})
endif()

# Configura nome do target
set_target_properties(Teste PROPERTIES OUTPUT_NAME teste)

# Configura libs linkadas
target_link_libraries(Teste Qt5::Core Qt5::Widgets)

#############################################
# Instalação
#############################################

get_filename_component(QT_BIN_DIR "${Qt5_DIR}/../../../bin" ABSOLUTE)
get_filename_component(QT_PLUGIN_DIR "${Qt5_DIR}/../../../plugins" ABSOLUTE)

# Instala o executável
install(TARGETS Teste DESTINATION bin)

# Instala as dependências do Qt5
install(FILES "${QT_BIN_DIR}/Qt5Core.dll" DESTINATION bin)
install(FILES "${QT_BIN_DIR}/Qt5Gui.dll" DESTINATION bin)
install(FILES "${QT_BIN_DIR}/Qt5Widgets.dll" DESTINATION bin)
install(FILES "${QT_PLUGIN_DIR}/platforms/qwindows.dll" DESTINATION bin/platforms)

# Instala as dependências do Windows 10 CRT
if(WIN32)
    set(WIN10_CRT_REDIST_DIR "C:/Program Files (x86)/Windows Kits/10/Redist/ucrt/DLLs/x86" CACHE STRING "Path of the Windows 10 Universal C Runtime DLLs." FORCE)

    file(GLOB CRTFiles "${WIN10_CRT_REDIST_DIR}/*.dll")
    foreach(CRTFile ${CRTFiles})
      install(FILES ${CRTFile} DESTINATION bin)
    endforeach()
endif()

# Instala demais dependências
include(InstallRequiredSystemLibraries)
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION bin)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.