Packaging a Qt application to deploy to the windows store
-
Hi, the last couple of days I've been trying to convert my Qt application into an appxupload package to be able to release it to the Windows Store. My application is a regular win32 app and Microsoft only accepts apps converted with Desktop Bridge in their store. To do this I create a Windows Application Packaging Project to be able to convert my app into an appxupload file and an appxbundle, which I've accomplished with relative ease. I started having problems when I tried to sideload my app with the appxbundle in my computer to test if it worked properly, but I got errors indicating that I was missing some of Qt dlls(Qt5Core, QtGui, Qt5Widgets... etc), I fixed this by adding them to windows packaging project and enabling them to copy themselves to the output directory- which succesfully solved the issue. But after this I got a new error telling me that "The application failed to start because it could not find or load the Qt Platform plugin windows. This error persists even when I add the folder platforms containing the qwindows.dll and I don't know what I need to do to fix it.
Here is a screenshot of the things that have been added to the Packaging Project:
I've added all the dependencies that were created by windeployqt.exe and set them to copy to the output directory. But I still get the same error everytime I test the package. Does anyone know how to properly package a Qt application for Desktop Bridge to be able to release it to the Windows Store, I don't know what I am doing wrong. -
@BryanTriana You probably need a qt.conf file.
Just add a qt.conf file in your directory with your binary that points to your plugins directory, like so:
[Paths] Plugins = plugins
Assuming your structure is something like:
base/ plugins/ platforms/
You can do this in code in your application too, but I always just preferred qt.conf since it was easy to change if needed.
-
This post is deleted!
-
@ambershark
I added the qt.conf file and it does work with that structure in a separate folder, but when I add all the files to the visual studio project to convert it into an appx I still get the same error. I figures its not a problem with Qt dependencies or platform folder, its simply that the plugin folder is not being created in the same directory as the executable when running the project. I've tried using post build events to include the folder alongside the executable but it still isn't working. I also added the directory within the code like the alternative solution you suggested, but now I know that that isn't the problem. Do you know how to deploy the plugins folder next to the executable when the application is being built(what do I need to do in visual studio to make it so the folder is accessible by the executable)? -
@BryanTriana Can you show me the directory structure of your project? A
dir /s
should gvie me the info I need, or you can type it out.Also share your project file (qmake, cmake, whatever) if possible.
Weirdly as part of the build (i.e. pre deployment) it should just work. You shouldn't need to deploy the plugin. It should just know where Qt and it's platform plugins are.
And finally since it fails in visual studio, run it in the debugger and show me a backtrace when it fails by not finding the plugin.
-
@ambershark
here is the directory:
https://www.dropbox.com/s/o81xxyasgi9rycy/directory.txt?dl=0
here is the callstack:
https://www.dropbox.com/s/2dvl11y8iuhveco/Callstack.txt?dl=0I don't know how to use qmake or cmake to share the project but you can look at the include files, source code and .pro file here:
https://github.com/InversePalindrome/DossierLayout -
@BryanTriana Interesting... This error seems to imply it didn't even get to the point of trying to load the platform plugin:
ucrtbase.dll!00007ffb6811b79e() Unknown Non-user code. Cannot find or open the file.
As for the qmake/cmake comment ... all I needed was the .pro file. I just didn't know what you used to build with, .pro files are qmake. :) That link is perfect.
If we assume that the crash is caused by the missing platform plugin we can just make a qt.conf in your binary directory that points to your system qt plugin dir, or you can make a plugins/platform and qt.conf as a build step. You can test this by building in visual studio, then manually adding a qt.conf to your Debug/ dir or whever you built that points to your plugins dir with the platform plugin. Then run that and see if it works. If it does then you can add a build step that does it for you. I can show you how to do that if you can't figure it out from the docs.
What confuses me is that it is able to find all your Qt dlls but not the plugin. Are you doing anything special for those after the build?
Edit: Oh and this is not ok:
INCLUDEPATH += C:\Users\Bryan\Desktop\DossierLayout\DossierLayout\include
You never want hardcoded absolute paths in your code or build. That should be replaces with a relative path and be part of your project. Basically only you on your specific system could build with this pro file because of that.
One more edit: You can also pass the directory to your plugins via an environment variable... This is done with
QT_PLUGIN_PATH=/path/to/your/qt/plugins
. That might be the easiest way in a dev environment, but definitely not in a release. -
Thank you, I got it working. But now I realized that for me to submit the app to the store I first have to convert it with the desktop app converter for desktop bridge, or the other option would be to port my app with the UWP kits included in Qt.
-
@BryanTriana Could you tell me how you made it to work? I did all of the above and still get the error "This application failed to start because no Qt platform plugin could be found". I created a msix package for the Windows store successfully, app get's installed, but fails to start.
-
Thank you for your advices!
But adding of QT_PLUGIN_PATH=/path/to/your/qt/plugins did not change the behavior of my program.
I tried to act "from opposite". I tried to find all occurrences of qsqlodbc.dll on my development platform. Then I renamed and then even replaced from their locations all these files. To my wonder, my program still works correctly either from qt creator or from command line. Program breaks only if I remove qtsql.dll from the location of exe-file.
So what can use QtSql.dll for extracting of QODBC driver if not qsqlodbc.dll.
But if das not need qsqlodbc.dll, why QODBC and other drivers are not accessible on the platform for deployment? -
@ambershark
file .pro:QT += core gui xml sql
win32:CONFIG += console
greaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = Name
TEMPLATE = app
VERSION = 1.5
HEADERS = "Header"DESTDIR = $$BUILD_TREE/bin
СONFIG += c++14
[Paths]
Plugins = pluginsSOURCES +=
main.cpp
mainwindow.cppHEADERS +=
FORMS +=
mainwindow.uiINCLUDEPATH += .
DEPENDPATH += .INCLUDEPATH += ./
DEPENDPATH += ./ -
Before offering to db, I put debug printing:
qDebug() << "db.drivers()=" << db.drivers();
It gives correct list of drivers on the development platform and empty set on deployment platform.if (db.isDriverAvailable("QODBC"))
db = QSqlDatabase::addDatabase("QODBC");
//It is a fragment of code for opening mdb (str is a full name to file from file-open dialog):
if (db.isOpen())
db.close();
qDebug() << "db.drivers()=" << db.drivers();
db.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ="+str+"; Uid=Admin; Pwd=; ExtendedAnsiSQL=1;");
bool ok = db.open();
if (ok)
{
// processing with sql
}