spark-store/src/main.cpp

290 lines
9.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<<<<<<< HEAD
#include "application.h"
#include "mainwindow-dtk.h"
#include "utils/utils.h"
#include <signal.h>
#include <execinfo.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fstream>
#include <execinfo.h>
#include <DSysInfo>
#include <QDate>
#include <QProcessEnvironment>
#include <QSettings>
#include <QFile>
#include <QStandardPaths>
#include <QSurfaceFormat>
#include <backend/DataCollectorAndUploader.h>
DCORE_USE_NAMESPACE
DWIDGET_USE_NAMESPACE
static QString buildDateTime;
void gatherInfo(FILE *fp, std::ofstream& logFile, const char* description) {
if (fp) {
char buffer[512];
logFile << description << ":\n";
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
buffer[strcspn(buffer, "\n")] = 0;
logFile << buffer << "\n";
}
pclose(fp);
} else {
logFile << "Failed to gather " << description << " info.\n";
}
}
void crashHandler(int sig) {
void *array[50];
size_t size = backtrace(array, 50);
if (size == 0) {
perror("backtrace");
exit(1);
}
time_t t = time(NULL);
struct tm tm = *localtime(&t);
char filename[128];
snprintf(filename, sizeof(filename), "/tmp/spark_store_crash_log_%04d%02d%02d_%02d%02d%02d.txt",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
std::ofstream logFile(filename, std::ios::out);
if (!logFile.is_open()) {
perror("ofstream");
exit(1);
}
logFile << "Please send this log to the developer. QQ Group: 872690351\n";
logFile << "Gitee: https://gitee.com/spark-store-project/spark-store/issues\n";
logFile << "Gihub: https://github.com/spark-store-project/spark-store/issues\n";
logFile << "Build Date and Time: " << buildDateTime.toStdString() << "\n";
gatherInfo(popen("cat ~/.config/spark-union/spark-store/config.ini", "r"), logFile, "User Config File");
// Collecting System Information
gatherInfo(popen("LANG=en_US.UTF-8 uname -m", "r"), logFile, "CPU Architecture");
gatherInfo(popen("LANG=en_US.UTF-8 lsb_release -a", "r"), logFile, "Distribution info");
gatherInfo(popen("LANG=en_US.UTF-8 lscpu", "r"), logFile, "All CPU Info");
gatherInfo(popen("LANG=en_US.UTF-8 free -h | grep Mem | awk '{print $2}'", "r"), logFile, "Memory Size");
logFile << "Error: signal " << sig << ":\n";
for (size_t i = 0; i < size; i++) {
char **strings = backtrace_symbols(&array[i], 1);
if (strings != NULL && strings[0] != NULL) {
logFile << strings[0] << "\n";
} else {
logFile << "Failed to get symbol.\n";
}
free(strings);
}
logFile.close();
char openCmd[256];
snprintf(openCmd, sizeof(openCmd), "xdg-open %s", filename);
if (system(openCmd) == -1) {
perror("system");
}
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
int main(int argc, char *argv[])
{
// 崩溃处理
signal(SIGSEGV, crashHandler); // 注册SIGSEGV处理函数
// Get build time
static const QDate buildDate = QLocale(QLocale::English).toDate(QString(__DATE__).replace(" ", " 0"), "MMM dd yyyy");
static const QTime buildTime = QTime::fromString(__TIME__, "hh:mm:ss");
buildDateTime = buildDate.toString("yyyy.MM.dd") + "-" + buildTime.toString("hh:mm:ss");
// NOTE: 提前设置组织名称和应用名称,避免配置文件位置错误
DApplication::setOrganizationName("spark-union");
DApplication::setApplicationName("spark-store");
Application::checkAppConfigLocation(); // 检查 ~/.config/spark-union/spark-store 文件夹是否存在
// 初始化 config.ini 配置文件
Utils::initConfig();
// 回传版本信息,不涉及个人隐私
DataCollectorAndUploader uploader;
QObject::connect(&uploader, &DataCollectorAndUploader::uploadSuccessful, [](){
qDebug() << "Data uploaded successfully";
});
QObject::connect(&uploader, &DataCollectorAndUploader::uploadFailed, [](QString error){
qDebug() << "Upload failed with error: " << error;
});
uploader.collectAndUploadData();
// Set display backend
Utils::setQPAPlatform();
// 龙芯机器配置,使得 DApplication 能正确加载 QtWebEngine
qputenv("DTK_FORCE_RASTER_WIDGETS", "FALSE");
// 设置 QtWebEngine 环境变量
QStringList chromium_flags;
// 浏览器开启 GPU 支持
// chromium_flags.append("--disable-features=UseModernMediaControls");
// chromium_flags.append("--disable-web-security");
// 全平台软件渲染Webkit
chromium_flags.append("--disable-gpu");
#if defined __sw_64__ || __loongarch__
chromium_flags.append("--no-sandbox");
#endif
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", chromium_flags.join(" ").toUtf8());
/**
* NOTE: https://zhuanlan.zhihu.com/p/550285855
* 避免 wayland 环境下从 QtWebEngine 后退回到 QWidget 时黑屏闪烁
*/
if (Utils::isWayland()) {
qputenv("QMLSCENE_DEVICE", "softwarecontext");
DApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
}
// 强制使用 DTK 平台插件
QVector<char *> fakeArgs(argc + 2);
fakeArgs[0] = argv[0];
fakeArgs[1] = const_cast<char *>("-platformtheme");
fakeArgs[2] = const_cast<char *>("deepin");
for (int i = 1; i < argc; i++)
{
fakeArgs[i + 2] = argv[i];
}
int fakeArgc = argc + 2; // QCoreApplication 的 argc 要用引用,避免 c++ 编译器优化
Application a(fakeArgc, fakeArgs.data());
// 设置版本和构建时间
a.setBuildDateTime(buildDateTime);
// 限制单实例运行
if (!a.setSingleInstance("spark-store"))
{
qWarning() << "Another instance has already started, activating...";
return -1;
}
MainWindow w;
a.setMainWindow(&w); // 设置应用程序主窗口,用于初始化关于对话框
if (argc > 1)
{
QString arg1 = argv[1];
if (arg1.trimmed().startsWith("spk://"))
{
w.openUrl(arg1);
}
}
w.show();
return a.exec();
}
=======
#include "mainwindow.h"
#include <QApplication>
#include <QProcess>
#include <QMessageBox>
#include <unistd.h> // for geteuid
#include <cstdlib> // for getenv
#include <QDebug> // For debugging output
bool isRoot() {
return geteuid() == 0;
}
bool elevateToRoot() {
QString program = QCoreApplication::applicationFilePath();
qDebug() << "Current application path:" << program;
QByteArray display = qgetenv("DISPLAY");
QByteArray xauthority = qgetenv("XAUTHORITY");
QStringList args;
args << "env"
<< "DISPLAY=" + display
<< "XAUTHORITY=" + xauthority
<< program;
QProcess process;
process.setProgram("pkexec");
process.setArguments(args);
qDebug() << "Attempting to elevate using pkexec with arguments:" << args;
process.start();
if (!process.waitForStarted(5000)) {
qDebug() << "Failed to start pkexec.";
return false;
}
// 阻塞等待提权进程退出(比如主程序窗口关闭)
if (!process.waitForFinished(-1)) { // 等待直到新进程退出
qDebug() << "pkexec process waitForFinished failed.";
return false;
}
int exitCode = process.exitCode();
QProcess::ExitStatus exitStatus = process.exitStatus();
qDebug() << "pkexec exit code:" << exitCode;
qDebug() << "pkexec exit status:" << exitStatus;
qDebug() << "pkexec stderr:" << process.readAllStandardError();
return (exitStatus == QProcess::NormalExit && exitCode == 0);
}
int main(int argc, char *argv[])
{
// 必须在 QGuiApplication 实例创建之前调用
// QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
QApplication a(argc, argv);
a.setWindowIcon(QIcon(":/resources/128*128/spark-update-tool.png"));
if (!isRoot()) {
qDebug() << "Not running as root. Attempting to elevate...";
if (!elevateToRoot()) {
qDebug() << "Elevation failed or pkexec command was not executed successfully.";
QMessageBox::critical(nullptr,
"权限不足",
"提权失败!\n\n您的系统可能不支持 `pkexec` 或 `polkit` 配置不正确,"
"或者您取消了授权。\n\n请尝试使用 `sudo` 命令运行此程序:"
"\n\n在终端中输入:\n`sudo " + QCoreApplication::applicationName() + "`");
return 0; // 提权失败,退出程序
} else {
// 如果 elevateToRoot 返回 true说明 pkexec 命令本身执行成功
// 但这并不意味着原始程序以 root 权限启动了
// 因为 elevateToRoot 启动的是一个新的进程,当前进程应该退出
// 否则会并行运行两个程序实例
qDebug() << "pkexec command executed successfully (new process likely started). Exiting current process.";
return 0; // 当前非root进程退出
}
} else {
qDebug() << "Running as root.";
}
MainWindow w;
w.show();
return a.exec();
}
>>>>>>> update-tool/dev