Qt deployed (macdeployqt) application does not create a file - c++

I'm facing the following problem:
I wrote a simple application to track working hours. Therefor I create a *.db file programmatically.
Launching the application from Qt Creator (debug or release) works perfectly fine.
I used the macdeployqt tool to get a *.dmg file. When starting the application now the method (see below) cannot open, respectively create the *.db file and I run out of ideas why. In addition to this, the application should output some *.csv files. This also fails.
One more information, running the application as administrator using the sudo command on terminal...well it works and the *.db file and *.csv files get created.
So I am quite sure it must deal with file permissions but I have no idea how to change this except for changing it in the information context menu but this didn't help at all.
Below the method for the *.db file which always returns false when not launching the app from Qt Creator:
QFile file(Globals::Environment::WORKING_DIRECTORY + "/" + "Records.db");
if(file.open(QIODevice::ReadWrite))
return true;
else
{
QMessageBox msg;
msg.setWindowTitle("Error");
msg.setText("Failed to create database file!");
msg.exec();
}
return false;
I am on MacOS 10.11.3.
Qt 5.5.1 (Clang 6.1 (Apple), 64 bit)
If more information is needed, I will provide it of course.
Thanks a lot for every help in advance.

Related

osx: external program (qprocess) crash if parent run with open, but works fine if parent run directly

I faced the strange situation on MacOS 10.13 and can't find what is the root of it.
I have 32-bit Qt application packed in a bundle. Because of MacOS limitation for one of the operations I need to start small 64-bit console binary that does a trick. This console binary placed in Contents/MacOS and I start it using QProcess.
Everything works fine if I run the main application from IDE. Also, everything fine if I open a terminal, cd to Contents/MacOS and run the main application directly.
But once I use "open myApp.app" or start it via UI, then QProcess exitCode() returns 255, which seems to mean crash.
Code for starting subprocess:
QProcess p;
p.start("./papply", QStringList() << osid << filepath);
p.waitForFinished(5000);
qDebug() << p.readAllStandardOutput();
qDebug() << p.readAllStandardError();
qDebug() << p.state();
if(p.state()==QProcess::Running)
{
qDebug() << "peapply freezed - kill";
p.kill();
return false;
}
qDebug() << "Apply" << osid << filepath << "=" << p.exitCode();
return p.exitCode()==0;
Any help will be very appreciated.
I have 32-bit Qt application packed in a bundle.
Firstly, just in-case you missed this, Apple have stated that the next version of the OS (10.14) will not support 32-bit applications, so you'll need to change this if you want to run this application on future versions of macOS.
If you use the debugger, or run a binary from a bundle's Contents/MacOS folder, it executes directly. In contrast, if you double-click on a binary, or use the open keyword from the terminal, a request is sent to Launch Services, to open the application on your behalf.
Launch Services (LS) maintains an association to an application's Bundle Identifier, which is located in the application bundle's Info.plist file.
When a request to open an application with LS occurs, LS is presented with the Bundle Identifier, from the application's plist and LS will execute the application that has been registered, with that identifier.
In the plist, we also have the key CFBundleExecutable, which is defined as the "(Recommended) Name of the bundle's executable file". This is the name of the binary that will likely be executed, residing in the Contents/MacOS folder.
Note, since LS launches the application associated with the given identifier, if there is a copy of the same application on your machine, with the same version number and identifier, it may not be necessarily executing the application you double-clicked, to run.
Therefore, the reason for the crash is most likely due to a different application being launched by LS and not the one you think is being executed. Ensure you have no other copies of the application residing on the machine.
If a crash report is generated, you should be able to see the path to the application, at the start of the images section, where it includes paths to dynamic libraries and frameworks.
While #TheDarkKnight provided great information that is not exactly an answer.
For people who will face the same situation:
In macOS bundle application has working directory related to bundle, but not to the execution file itself as it happens in Windows.
So in my case next code works:
QString path = qApp->applicationDirPath();
if(!path.endsWith("/"))
path += "/";
QProcess p;
p.start(path + "papply", QStringList() << osid << filepath);

Solved but not explained: Qt5.5 webkitwidgets, missing DLL, unexpected crash

I made a very simple and boring postal code -> city lookup program (it uses an online api).
I wanted to add functionality which allows to select any country (which the api can process). For this I wanted to load the main page and parse the DOM to get all the countries. This requires webkitwidgets. http://www.zippopotam.us/#where (this is the table I want to extract the information from)
Unfortunately, when attempting to run the program it never even starts and gives me the Application Output:
Starting ZipcodeToLocation.exe...
The program has unexpectedly finished.
ZipcodeToLocation.exe crashed
So I try running the debugger:
An exception was triggered:
Exception at 0x77cbd4f2, code: 0xc0000135: DLL not found, flags=0x0.
During startup program exited with code 0xc0000135.
Weird... so I try finding this error message on the internet and nothing really helps me. I think maybe I set something up wrong, so I open the webkitwidgets examples and compile those. When attempting to run - same error.
Using programs like some dependency walker didn't really help me much either.
I ran the MaintananceTool to check whether I was missing something, but I wasn't able to detect anything.
Im running QtCreator on Windows btw.
My .pro
QT += core gui webkitwidgets network
CONFIG += c++14
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ZipcodeToLocation
TEMPLATE = app
SOURCES += main.cpp\
MainWindow.cpp
HEADERS += MainWindow.hpp
FORMS += MainWindow.ui
If I remove the following portion from my main window ctor, everything runs es expected:
auto page = new QWebPage(this);
page->mainFrame()->load(QUrl("http://www.zippopotam.us"));
Note: this is currently the only section using webkitwidgets.
I would be really happy if someone could help me overcome this roadblock and has any suggestions on what might be going wrong.
Edit: Just to make it complete, a screenshot of the depends run: https://i.imgur.com/YWpdlO6.png?1
The german part translates to "The System can't find specified file".
Edit2: If you have QtCreator installed and want to attempt reproducing my error, create new QWidgets application, edit your .pro like so:
QT += core gui webkitwidgets
and this line at the end of MainWindow ctor (probably any usage of webkitwidgets would do):
#include <QWebKitWidgets>
//...
QWebPage *page = new QWebPage(this);
Edit3: As a reaction to a recent comment, I tried copying all dlls from the Qt directory to the .exe location (release) and tried running it from there. It said "Missing Qt5Positioning.dll". Which is weird, because I am not using the location module... But I guess that explains the missing dll crash?
Edit4:
I finally had enough and simply completely reinstalled Qt from scratch. Somehow my installation had to be messed up, because after that the problem vanished.

QFileDialog freezes on close/destructor (with selected file or cancel)

I'm developing applications in qt with Ubuntu 15.04 and the respective qt pakage 5.4. For some reason, out of nowhere the application would freeze after selecting a file within a QFileDialog (or even cancelling).
I found some similar topics on the web but most were concerned with a now resolved bug in qt 5.1 and (non-)native QFileDialogs.
Then I found out this is related to more than just my own application - even qtcreator would freeze on leaving the QFileDialog, now.
There seems to be a deadlock in the destructor of QFileDialog.
The following snippet is from qsettings.cpp (line 1382), within void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QLockFile lockFile(confFile->name + QLatin1String(".lock"));
if (!readOnly) {
if (!confFile->isWritable() || !lockFile.lock() ) {
setStatus(QSettings::AccessError);
return;
}
}
It turns out some other qt application has left a lock file which causes all other applications' QFileDialog destructor to be deadlocked within the above lock call.
I searched for .lock files in my home folder and after deleting
./.config/QtProject.conf.lock and a second file similar to .config/USERNAME/APPTARGETNAME.conf.lock
the QFileDialog works well, agian.
I just now can't reproduce which of the two files did cause the deadlock.
Hope this helps anyone in a similar situation!

How to launch the associated application for a file / directory / URL?

Linux seems to be easy: xdg-open <file/directory/URL>.
Apparently, Mac is similar: open should be used instead of xdg-open. I don't have access to a Mac so I couldn't test it.
For Windows, I found 4 different suggestions and those that I have tried failed.
Is there a non-java, cross platform way to launch the associated application for a certain file type?
suggests start
How to give focus to default program of shell-opened file, from Java? suggests
cmd /c start ...
How to open user system preferred editor for given file?
How to Find Out Default File Opener with Java?
suggest RUNDLL32.exe
What is the correct way to use ShellExecute() in C to open a .txt
Open file with Windows' native program within C++ code
How to use ShellExecute to open html files in Windows using C++? suggest
ShellExecute
I have tried the first 3 with system() and QProcess::startDetached() and "http://www.stackoverflow.com" as argument but they all failed; start works just fine from the command line though. I haven't tried ShellExecute yet.
What is the Windows equivalent of xdg-open? It seem to me, it is start but why did my attempts with start fail?
Is ShellExecute my only option?
EDIT I thought QDesktopServices::openUrl() was for web pages only because it did not work for files or directories.
After some debugging I figured out that if I replace \\ with / in the path on Windows, it works for files but the directories are still not opened. Any ideas what I am doing wrong?
QDir dir("C:/Documents and Settings/ali");
qDebug() << "Exists? " << dir.exists();
qDebug() << dir.absolutePath();
QDesktopServices::openUrl(QUrl(dir.absolutePath()));
qDebug() << "External app called";
Application Output:
Exists? true
"C:/Documents and Settings/ali"
External app called
But nothing happens, the directory is not opened. On Linux, directories are opened with the default file manager as expected.
SOLUTION: Due to the Qt bug and Windows quirks (malformed application window), I ended up using ShellExecute. That gives me enough flexibility to achieve exactly what I want at some expense...
Why don't you just use Qt's support for this? For example:
QDesktopServices::openUrl(QUrl("/home/realnc/test.pdf"));
This opens the document in Acrobat Reader. In general, it obeys the preferred application settings in my OS for all file types that have one or more applications associated with them. Best of all, it's platform-independent.
Edit:
The fact that it opens directories on Linux but not on Windows smells like a bug. It might be best to report this on Qt's bug tracker. In the meantime, you could have a workaround for Windows for when the file is a directory:
#ifdef Q_WS_WIN
if (QFileInfo(path).isDir())
QProcess::startDetached("explorer", QStringList(path));
else
#endif
QDesktopServices::openUrl(QUrl(path));
You can also do it with cmd.exe's start command, but you'll get an ugly terminal pop up for a few fractions of a second:
QProcess::startDetached("cmd", QStringList() << "/C" << "start"
<< QDir::toNativeSeparators(path));

Issue with QCA (Qt C++ Encryption Library) run on windows 7

I am using Qt 4.8.1, MinGW compiler and Qt Creator, all on windows 7. I want to add an encryption/ decryption library to my project. After searching the web for couple days I found QCA. Fortunately I found a pre-built version using the same C++ compiler I am using, and a pre-built version of the needed plugins.
I followed the instructions to add the QCA library to my project. I used a code like this to encrypt using AES:
QCA::Initializer init = QCA::Initializer();
//Here where the execution stops
QCA::SymmetricKey key = QCA::SymmetricKey(16);
QCA::InitializationVector iv = QCA::InitializationVector(16);
QCA::Cipher cipher = QCA::Cipher(QString("aes128"), QCA::Cipher::CBC,
QCA::Cipher::DefaultPadding, QCA::Encode,
key, iv);
if (!QCA::isSupported("aes128-cbc-pkcs7"))
{
qDebug() << "AES128 is not supported";
return;
}
The code compiles just fine but when I run the application stops with unknown reason.
I really got tired from this bug, if anybody can help it will be very very very appreciated.
For future programmers that might get stuck on this
QCA loads the plugins at runtime, so even if it compiles fine, if the plugin is not in a searchable folder, it won't load.
You can check if that's the problem by calling qDebug() << QCA::supportedFeatures();. If the plugins are not being loaded, you'll get something like:
("random", "md5", "sha1", "keystorelist")
You should be able to see the folders QCA is looking up by calling:
qDebug("%s", QCA::pluginDiagnosticText().toUtf8().constData());
Apparently, plugins must be placed in a subdirectory called crypto in the libs root directory.
You can check for all the paths where Qt looks for libraries using:
qDebug() << QCoreApplication::instance()->libraryPaths();
This documentation might have some useful information: http://doc.qt.io/qt-4.8/qpluginloader.html