int myKill(pid_t pid, int signal) { if (pid == 0) { return 0; } #ifdef Q_OS_WIN32 if (signal == 0) { QProcess kill; kill.start( QStringLiteral("TASKLIST"), QStringList() << QStringLiteral("/FI") << QString("PID eq %1").arg(pid) << QStringLiteral("/NH") ); if (!kill.waitForStarted()) { qWarning("QProcess can't start \"%s\"", kill.program().toStdString().c_str()); return -1; } if (!kill.waitForFinished()) { qWarning("\"%s\" didn't write anything", kill.program().toStdString().c_str()); return -1; } return (kill.readAll().contains(QByteArray::number(pid)) ? 0 : -1); } QString cmd = QString("TASKKILL /F /PID %1").arg(pid); errno = system(cmd.toStdString().c_str()); return (errno == 128 ? 0 : errno); #else return kill(pid, signal); #endif }
static const QString msgProcessError(const QProcess &process, const QString &what) { QString result; QTextStream(&result) << what << ": \"" << process.program() << ' ' << process.arguments().join(QLatin1Char(' ')) << "\": " << process.errorString(); return result; }
static Result runApp(const QString &execPath, const QStringList &args) { // QString outPipePath = FS::TmpFilePath("pipeOut"); QProcess app; app.setProgram(execPath); app.setArguments(args); app.start(); if (!app.waitForStarted()) { qWarning() << "Cmd Exec Failed:" << app.errorString(); return Result(Result::Failed, app.errorString(), "", app.program()); } if (!app.waitForFinished(-1)) { qWarning() << "waitForFinished Failed:" << app.errorString(); return Result(Result::Failed, app.errorString(), "", app.program()); } auto standardError = app.readAllStandardError(); if (QProcess::NormalExit != app.exitStatus()) { qWarning() << "exitStatus error:" << app.exitStatus() << standardError << app.program(); return Result(Result::Failed, standardError, "", app.program()); } if (0 != app.exitCode()) { qWarning() << "exitCode error:" << app.exitCode() << standardError << app.program(); return Result(Result::Failed, standardError, "", app.program()); } Result rest(Result::Success, standardError, app.readAllStandardOutput()); return rest; }
void BakaEngine::BakaSh(QStringList &args) { if(!args.empty()) { QString arg = args.front(); args.pop_front(); QProcess *p = new QProcess(this); p->start(arg, args); connect(p, &QProcess::readyRead, [=] { Print(p->readAll(), QString("%0(%1))").arg(p->program(), QString::number(quintptr(p)))); }); // connect(p, &QProcess::finished, // [=](int, QProcess::ExitStatus) // { // delete p; // }); } else RequiresParameters("mpv"); }
static int assemble(Input input, const QInstaller::Settings &settings, const QString &signingIdentity) { #ifdef Q_OS_OSX if (QInstaller::isInBundle(input.installerExePath)) { const QString bundle = input.installerExePath; // if the input file was a bundle const QSettings s(QString::fromLatin1("%1/Contents/Info.plist").arg(input.installerExePath), QSettings::NativeFormat); input.installerExePath = QString::fromLatin1("%1/Contents/MacOS/%2").arg(bundle) .arg(s.value(QLatin1String("CFBundleExecutable"), QFileInfo(input.installerExePath).completeBaseName()).toString()); } const bool createDMG = input.outputPath.endsWith(QLatin1String(".dmg")); if (createDMG) input.outputPath.replace(input.outputPath.length() - 4, 4, QLatin1String(".app")); const bool isBundle = input.outputPath.endsWith(QLatin1String(".app")); const QString bundle = isBundle ? input.outputPath : QString(); const BundleBackup bundleBackup(bundle); if (isBundle) { // output should be a bundle const QFileInfo fi(input.outputPath); const QString contentsResourcesPath = fi.filePath() + QLatin1String("/Contents/Resources/"); QInstaller::mkpath(fi.filePath() + QLatin1String("/Contents/MacOS")); QInstaller::mkpath(contentsResourcesPath); { QFile pkgInfo(fi.filePath() + QLatin1String("/Contents/PkgInfo")); pkgInfo.open(QIODevice::WriteOnly); QTextStream pkgInfoStream(&pkgInfo); pkgInfoStream << QLatin1String("APPL????") << endl; } QString iconFile; if (QFile::exists(settings.installerApplicationIcon())) { iconFile = settings.installerApplicationIcon(); } else { iconFile = QString::fromLatin1(":/resources/default_icon_mac.icns"); } const QString iconTargetFile = fi.completeBaseName() + QLatin1String(".icns"); QFile::copy(iconFile, contentsResourcesPath + iconTargetFile); if (QDir(qApp->applicationDirPath() + QLatin1String("/qt_menu.nib")).exists()) { copyDirectoryContents(qApp->applicationDirPath() + QLatin1String("/qt_menu.nib"), contentsResourcesPath + QLatin1String("/qt_menu.nib")); } QFile infoPList(fi.filePath() + QLatin1String("/Contents/Info.plist")); infoPList.open(QIODevice::WriteOnly); QTextStream plistStream(&infoPList); plistStream << QLatin1String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") << endl; plistStream << QLatin1String("<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs" "/PropertyList.dtd\">") << endl; plistStream << QLatin1String("<plist version=\"0.9\">") << endl; plistStream << QLatin1String("<dict>") << endl; plistStream << QLatin1String(" <key>CFBundleIconFile</key>") << endl; plistStream << QLatin1String(" <string>") << iconTargetFile << QLatin1String("</string>") << endl; plistStream << QLatin1String(" <key>CFBundlePackageType</key>") << endl; plistStream << QLatin1String(" <string>APPL</string>") << endl; plistStream << QLatin1String(" <key>CFBundleGetInfoString</key>") << endl; #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) plistStream << QLatin1String(" <string>") << QLatin1String(QUOTE(IFW_VERSION_STR)) << ("</string>") << endl; #undef QUOTE #undef QUOTE_ plistStream << QLatin1String(" <key>CFBundleSignature</key>") << endl; plistStream << QLatin1String(" <string> ???? </string>") << endl; plistStream << QLatin1String(" <key>CFBundleExecutable</key>") << endl; plistStream << QLatin1String(" <string>") << fi.completeBaseName() << QLatin1String("</string>") << endl; plistStream << QLatin1String(" <key>CFBundleIdentifier</key>") << endl; plistStream << QLatin1String(" <string>com.yourcompany.installerbase</string>") << endl; plistStream << QLatin1String(" <key>NOTE</key>") << endl; plistStream << QLatin1String(" <string>This file was generated by Qt Installer Framework.</string>") << endl; plistStream << QLatin1String(" <key>NSPrincipalClass</key>") << endl; plistStream << QLatin1String(" <string>NSApplication</string>") << endl; plistStream << QLatin1String("</dict>") << endl; plistStream << QLatin1String("</plist>") << endl; input.outputPath = QString::fromLatin1("%1/Contents/MacOS/%2").arg(input.outputPath) .arg(fi.completeBaseName()); } #elif defined(Q_OS_LINUX) Q_UNUSED(settings) #endif QTemporaryFile file(input.outputPath); if (!file.open()) { throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(input.installerExePath, input.outputPath, file.errorString())); } const QString tempFile = file.fileName(); file.close(); file.remove(); QFile instExe(input.installerExePath); if (!instExe.copy(tempFile)) { throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(instExe.fileName(), tempFile, instExe.errorString())); } QtPatch::patchBinaryFile(tempFile, QByteArray("MY_InstallerCreateDateTime_MY"), QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-dd - HH:mm:ss")).toLatin1()); input.installerExePath = tempFile; #if defined(Q_OS_WIN) // setting the windows icon must happen before we append our binary data - otherwise they get lost :-/ if (QFile::exists(settings.installerApplicationIcon())) { // no error handling as this is not fatal setApplicationIcon(tempFile, settings.installerApplicationIcon()); } #elif defined(Q_OS_OSX) if (isBundle) { // no error handling as this is not fatal const QString copyscript = QDir::temp().absoluteFilePath(QLatin1String("copylibsintobundle.sh")); QFile::copy(QLatin1String(":/resources/copylibsintobundle.sh"), copyscript); QFile::rename(tempFile, input.outputPath); chmod755(copyscript); QProcess p; p.start(copyscript, QStringList() << bundle); p.waitForFinished(-1); QFile::rename(input.outputPath, tempFile); QFile::remove(copyscript); } #endif QTemporaryFile out; QString targetName = input.outputPath; #ifdef Q_OS_OSX QDir resourcePath(QFileInfo(input.outputPath).dir()); resourcePath.cdUp(); resourcePath.cd(QLatin1String("Resources")); targetName = resourcePath.filePath(QLatin1String("installer.dat")); #endif { QFile target(targetName); if (target.exists() && !target.remove()) { qCritical("Cannot remove target %s: %s", qPrintable(target.fileName()), qPrintable(target.errorString())); QFile::remove(tempFile); return EXIT_FAILURE; } } try { QInstaller::openForWrite(&out); QFile exe(input.installerExePath); #ifdef Q_OS_OSX if (!exe.copy(input.outputPath)) { throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(exe.fileName(), input.outputPath, exe.errorString())); } #else QInstaller::openForRead(&exe); QInstaller::appendData(&out, &exe, exe.size()); #endif foreach (const QInstallerTools::PackageInfo &info, input.packages) { QInstaller::ResourceCollection collection; collection.setName(info.name.toUtf8()); qDebug() << "Creating resource archive for" << info.name; foreach (const QString &file, info.copiedFiles) { const QSharedPointer<Resource> resource(new Resource(file)); qDebug().nospace() << "Appending " << file << " (" << humanReadableSize(resource->size()) << ")"; collection.appendResource(resource); } input.manager.insertCollection(collection); } const QList<QInstaller::OperationBlob> operations; BinaryContent::writeBinaryContent(&out, operations, input.manager, BinaryContent::MagicInstallerMarker, BinaryContent::MagicCookie); } catch (const Error &e) { qCritical("Error occurred while assembling the installer: %s", qPrintable(e.message())); QFile::remove(tempFile); return EXIT_FAILURE; } if (!out.rename(targetName)) { qCritical("Cannot write installer to %s: %s", targetName.toUtf8().constData(), out.errorString().toUtf8().constData()); QFile::remove(tempFile); return EXIT_FAILURE; } out.setAutoRemove(false); #ifndef Q_OS_WIN chmod755(out.fileName()); #endif QFile::remove(tempFile); #ifdef Q_OS_OSX if (isBundle && !signingIdentity.isEmpty()) { qDebug() << "Signing .app bundle..."; QProcess p; p.start(QLatin1String("codesign"), QStringList() << QLatin1String("--force") << QLatin1String("--deep") << QLatin1String("--sign") << signingIdentity << bundle); if (!p.waitForFinished(-1)) { qCritical("Failed to sign app bundle: error while running '%s %s': %s", p.program().toUtf8().constData(), p.arguments().join(QLatin1Char(' ')).toUtf8().constData(), p.errorString().toUtf8().constData()); return EXIT_FAILURE; } if (p.exitStatus() == QProcess::NormalExit) { if (p.exitCode() != 0) { qCritical("Failed to sign app bundle: running codesign failed " "with exit code %d: %s", p.exitCode(), p.readAllStandardError().constData()); return EXIT_FAILURE; } } qDebug() << "done."; } bundleBackup.release(); if (createDMG) { qDebug() << "creating a DMG disk image..."; const QString volumeName = QFileInfo(input.outputPath).fileName(); const QString imagePath = QString::fromLatin1("%1/%2.dmg") .arg(QFileInfo(bundle).path()) .arg(volumeName); // no error handling as this is not fatal QProcess p; p.start(QLatin1String("/usr/bin/hdiutil"), QStringList() << QLatin1String("create") << imagePath << QLatin1String("-srcfolder") << bundle << QLatin1String("-ov") << QLatin1String("-volname") << volumeName << QLatin1String("-fs") << QLatin1String("HFS+")); qDebug() << "running " << p.program() << p.arguments(); p.waitForFinished(-1); qDebug() << "removing" << bundle; QDir(bundle).removeRecursively(); qDebug() << "done."; } #else Q_UNUSED(signingIdentity) #endif return EXIT_SUCCESS; }