mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-07-09 23:25:58 +08:00
fix: 尝试修复 ISSUE #I68I8W 安装结束时随机崩溃问题
暂时未知,目前怀疑安装结束后,DownloadItem 触发 finished() 信号,在详情页槽函数中执行 disconnect 操作时导致崩溃 Log: 去除 disconnect 操作;修改可能造成问题的控件指针获取方式;修复多线程执行下载安装操作时跨线程相关警告 * 该提交可能存在严重问题,建议多进行测试;如果存在问题,及时 revert 该提交
This commit is contained in:
parent
eaf268a10d
commit
cb093dcc2b
@ -145,17 +145,19 @@ void DownloadController::startDownload(const QString &url)
|
||||
command.append(aria2NoSeeds.toUtf8());
|
||||
}
|
||||
qDebug() << command;
|
||||
auto cmd = new QProcess(this);
|
||||
cmd->setProcessChannelMode(QProcess::MergedChannels);
|
||||
cmd->setProgram("aria2c");
|
||||
cmd->setArguments(command);
|
||||
cmd->start();
|
||||
cmd->waitForStarted(); //等待启动完成
|
||||
|
||||
QObject::connect(cmd, &QProcess::readyReadStandardOutput, [&]()
|
||||
bool downloadSuccess = true;
|
||||
QProcess cmd;
|
||||
cmd.setProcessChannelMode(QProcess::MergedChannels);
|
||||
cmd.setProgram("aria2c");
|
||||
cmd.setArguments(command);
|
||||
cmd.start();
|
||||
cmd.waitForStarted(-1); //等待启动完成
|
||||
|
||||
connect(&cmd, &QProcess::readyReadStandardOutput, [&]()
|
||||
{
|
||||
//通过读取输出计算下载速度
|
||||
QString message = cmd->readAllStandardOutput().data();
|
||||
QString message = cmd.readAllStandardOutput().data();
|
||||
// qDebug() << message;
|
||||
message = message.replace(" ", "");
|
||||
QStringList list;
|
||||
@ -195,17 +197,21 @@ void DownloadController::startDownload(const QString &url)
|
||||
emit downloadProcess(speedInfo, downloadSizeRecord, fileSize);
|
||||
}
|
||||
});
|
||||
QObject::connect(cmd, &QProcess::readyReadStandardError, [&]()
|
||||
connect(&cmd, &QProcess::readyReadStandardError, [&]()
|
||||
{
|
||||
emit errorOccur(cmd->readAllStandardError().data());
|
||||
return;
|
||||
emit errorOccur(cmd.readAllStandardError().data());
|
||||
downloadSuccess = false;
|
||||
cmd.close();
|
||||
});
|
||||
|
||||
auto pidNumber = cmd->processId();
|
||||
this->pidNumber = pidNumber;
|
||||
while (cmd->waitForFinished(-1))
|
||||
pidNumber = cmd.processId();
|
||||
|
||||
cmd.waitForFinished(-1);
|
||||
cmd.close();
|
||||
|
||||
if(!downloadSuccess)
|
||||
{
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
// 统计下载量
|
||||
@ -218,7 +224,7 @@ void DownloadController::startDownload(const QString &url)
|
||||
mailProcess.start(SenderdPath.toUtf8(), QStringList() << metaUrl << "HD70642");
|
||||
mailProcess.waitForStarted();
|
||||
mailProcess.waitForFinished(3000);
|
||||
mailProcess.deleteLater();
|
||||
mailProcess.close();
|
||||
|
||||
emit downloadFinished(); });
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
|
||||
private:
|
||||
int threadNum;
|
||||
int pidNumber = -1;
|
||||
qint64 pidNumber = -1;
|
||||
QString filename;
|
||||
qint64 fileSize;
|
||||
QVector<QPair<qint64, qint64>> ranges;
|
||||
|
@ -291,34 +291,39 @@ void AppIntoPage::initConnections()
|
||||
|
||||
void AppIntoPage::isDownloading(const QUrl &url)
|
||||
{
|
||||
if (dw->getUrlList().lastIndexOf(url) == -1)
|
||||
int index = dw->getUrlList().lastIndexOf(url);
|
||||
if (index == -1)
|
||||
{
|
||||
ui->downloadButton->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
DownloadItem *item = dw->getDIList().at(index);
|
||||
if (item == nullptr)
|
||||
{
|
||||
ui->downloadButton->setEnabled(false);
|
||||
ui->downloadButton->setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ui->downloadButton->setEnabled(false);
|
||||
ui->pushButton_3->hide();
|
||||
if (dw->getDIList()[dw->getUrlList().lastIndexOf(url)]->download == 2)
|
||||
if (item->download == 2)
|
||||
{
|
||||
ui->downloadButton->setEnabled(true);
|
||||
ui->downloadButton->setText(tr("Download"));
|
||||
}
|
||||
if (dw->getDIList()[dw->getUrlList().lastIndexOf(url)]->download == 1)
|
||||
if (item->download == 1)
|
||||
{
|
||||
ui->downloadButton->setEnabled(true);
|
||||
ui->downloadButton->setText(tr("Install"));
|
||||
}
|
||||
if (dw->getDIList()[dw->getUrlList().lastIndexOf(url)]->isInstall)
|
||||
if (item->isInstall)
|
||||
{
|
||||
ui->downloadButton->setEnabled(false);
|
||||
ui->downloadButton->setText(tr("Installing"));
|
||||
return;
|
||||
}
|
||||
if (dw->getDIList()[dw->getUrlList().lastIndexOf(url)]->download == 3)
|
||||
if (item->download == 3)
|
||||
{
|
||||
ui->downloadButton->setEnabled(true);
|
||||
ui->downloadButton->setText(tr("Reinstall"));
|
||||
@ -368,32 +373,39 @@ void AppIntoPage::setAppinfoTags(const QStringList &tagList)
|
||||
|
||||
void AppIntoPage::on_downloadButton_clicked()
|
||||
{
|
||||
QString downloadUrl = SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString();
|
||||
if (ui->downloadButton->text() == tr("Install"))
|
||||
{
|
||||
dw->getDIList()[dw->getUrlList().lastIndexOf(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString())]->install(0);
|
||||
isDownloading(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString());
|
||||
connect(dw->getDIList()[dw->getUrlList().lastIndexOf(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString())], &DownloadItem::finished, [=]()
|
||||
{
|
||||
isDownloading(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString());
|
||||
disconnect(dw->getDIList()[dw->getUrlList().lastIndexOf(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString())], &DownloadItem::finished, nullptr, nullptr); });
|
||||
DownloadItem *item = dw->getDIList()[dw->getUrlList().lastIndexOf(downloadUrl)];
|
||||
if (item == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
connect(item, &DownloadItem::finished, [=]() { isDownloading(downloadUrl); });
|
||||
|
||||
item->install(0);
|
||||
isDownloading(downloadUrl);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
emit clickedDownloadBtn();
|
||||
|
||||
dw->addItem(info["Name"].toString(), info["Filename"].toString(), info["Pkgname"].toString(), iconpixmap, SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString());
|
||||
DownloadItem *item = dw->addItem(info["Name"].toString(), info["Filename"].toString(), info["Pkgname"].toString(), iconpixmap, downloadUrl);
|
||||
if (item == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui->downloadButton->text() == tr("Reinstall"))
|
||||
{
|
||||
dw->getDIList()[dw->allDownload - 1]->reinstall = true;
|
||||
item->reinstall = true;
|
||||
}
|
||||
ui->downloadButton->setEnabled(false);
|
||||
connect(dw->getDIList()[dw->getUrlList().lastIndexOf(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString())], &DownloadItem::finished, [=]()
|
||||
{
|
||||
isDownloading(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString());
|
||||
disconnect(dw->getDIList()[dw->getUrlList().lastIndexOf(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString())], &DownloadItem::finished, nullptr, nullptr); });
|
||||
connect(item, &DownloadItem::finished, [=]() { isDownloading(downloadUrl); });
|
||||
|
||||
isDownloading(SparkAPI::getServerUrl() + "store" + spk.path() + "/" + info["Filename"].toString());
|
||||
isDownloading(downloadUrl);
|
||||
}
|
||||
|
||||
void AppIntoPage::on_pushButton_3_clicked()
|
||||
|
@ -105,76 +105,10 @@ void DownloadItem::install(int t)
|
||||
ui->label_2->setToolTip(tr("Installing"));
|
||||
|
||||
QtConcurrent::run([=]()
|
||||
{
|
||||
QProcess installer;
|
||||
switch(t)
|
||||
{
|
||||
case 0:
|
||||
installer.start("pkexec", QStringList() << "ssinstall" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 1:
|
||||
installer.start("deepin-deb-installer", QStringList() << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 2:
|
||||
installer.start("pkexec", QStringList() << "gdebi" << "-n" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
}
|
||||
{
|
||||
slotAsyncInstall(t);
|
||||
});
|
||||
|
||||
bool haveError = false;
|
||||
bool notRoot = false;
|
||||
installer.waitForFinished(-1); // 不设置超时
|
||||
out = installer.readAllStandardOutput();
|
||||
|
||||
QStringList everyOut = out.split("\n");
|
||||
for (int i = 0; i < everyOut.size(); i++)
|
||||
{
|
||||
if(everyOut[i].left(2) == "E:")
|
||||
{
|
||||
haveError = true;
|
||||
}
|
||||
if(everyOut[i].right(14) == "Not authorized")
|
||||
{
|
||||
notRoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
QProcess isInstall;
|
||||
isInstall.start("dpkg", QStringList() << "-s" << pkgName);
|
||||
isInstall.waitForFinished(180*1000); // 默认超时 3 分钟
|
||||
int error = QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
||||
if (error == 0 && !haveError)
|
||||
{
|
||||
ui->pushButton_install->hide();
|
||||
Utils::sendNotification("spark-store",tr("Spark Store"),ui->label->text() + " " + tr("Installation complete."));
|
||||
ui->label_2->setText(tr("Finish"));
|
||||
ui->label_2->setToolTip(tr("Finish"));
|
||||
download = 3;
|
||||
ui->pushButton_3->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_install->setText(tr("Retry"));
|
||||
download = 1;
|
||||
Utils::sendNotification("spark-store",tr("Spark Store"),tr("Error happened in dpkg progress , you can try it again."));
|
||||
ui->label_2->setText(tr("Error happened in dpkg progress , you can try it again"));
|
||||
ui->label_2->setToolTip(tr("Error happened in dpkg progress , you can try it again"));
|
||||
ui->pushButton_3->show();
|
||||
}
|
||||
|
||||
if (notRoot)
|
||||
{
|
||||
Utils::sendNotification("spark-store",tr("Spark Store"),tr("dpkg progress had been aborted,you can retry installation."));
|
||||
ui->label_2->setText(tr("dpkg progress had been aborted,you can retry installation"));
|
||||
ui->label_2->setToolTip(tr("dpkg progress had been aborted,you can retry installation"));
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_3->hide();
|
||||
}
|
||||
|
||||
ui->widget_spinner->hide();
|
||||
DownloadItem::isInstall = false;
|
||||
emit finished(); });
|
||||
// emit finished();
|
||||
qDebug() << ui->label_filename->text().toUtf8();
|
||||
}
|
||||
}
|
||||
@ -207,3 +141,75 @@ void DownloadItem::on_pushButton_3_clicked()
|
||||
output_w->layout()->addWidget(textbrowser);
|
||||
output_w->show();
|
||||
}
|
||||
|
||||
void DownloadItem::slotAsyncInstall(int t)
|
||||
{
|
||||
QProcess installer;
|
||||
switch(t)
|
||||
{
|
||||
case 0:
|
||||
installer.start("pkexec", QStringList() << "ssinstall" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 1:
|
||||
installer.start("deepin-deb-installer", QStringList() << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
case 2:
|
||||
installer.start("pkexec", QStringList() << "gdebi" << "-n" << "/tmp/spark-store/" + ui->label_filename->text().toUtf8());
|
||||
break;
|
||||
}
|
||||
|
||||
bool haveError = false;
|
||||
bool notRoot = false;
|
||||
installer.waitForFinished(-1); // 不设置超时
|
||||
out = installer.readAllStandardOutput();
|
||||
|
||||
QStringList everyOut = out.split("\n");
|
||||
for (int i = 0; i < everyOut.size(); i++)
|
||||
{
|
||||
if(everyOut[i].left(2) == "E:")
|
||||
{
|
||||
haveError = true;
|
||||
}
|
||||
if(everyOut[i].right(14) == "Not authorized")
|
||||
{
|
||||
notRoot = true;
|
||||
}
|
||||
}
|
||||
|
||||
QProcess isInstall;
|
||||
isInstall.start("dpkg", QStringList() << "-s" << pkgName);
|
||||
isInstall.waitForFinished(180*1000); // 默认超时 3 分钟
|
||||
int error = QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
||||
if (error == 0 && !haveError)
|
||||
{
|
||||
ui->pushButton_install->hide();
|
||||
Utils::sendNotification("spark-store",tr("Spark Store"),ui->label->text() + " " + tr("Installation complete."));
|
||||
ui->label_2->setText(tr("Finish"));
|
||||
ui->label_2->setToolTip(tr("Finish"));
|
||||
download = 3;
|
||||
ui->pushButton_3->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_install->setText(tr("Retry"));
|
||||
download = 1;
|
||||
Utils::sendNotification("spark-store",tr("Spark Store"),tr("Error happened in dpkg progress , you can try it again."));
|
||||
ui->label_2->setText(tr("Error happened in dpkg progress , you can try it again"));
|
||||
ui->label_2->setToolTip(tr("Error happened in dpkg progress , you can try it again"));
|
||||
ui->pushButton_3->show();
|
||||
}
|
||||
|
||||
if (notRoot)
|
||||
{
|
||||
Utils::sendNotification("spark-store",tr("Spark Store"),tr("dpkg progress had been aborted,you can retry installation."));
|
||||
ui->label_2->setText(tr("dpkg progress had been aborted,you can retry installation"));
|
||||
ui->label_2->setToolTip(tr("dpkg progress had been aborted,you can retry installation"));
|
||||
ui->pushButton_install->show();
|
||||
ui->pushButton_3->hide();
|
||||
}
|
||||
|
||||
ui->widget_spinner->hide();
|
||||
DownloadItem::isInstall = false;
|
||||
emit finished();
|
||||
}
|
||||
|
@ -59,6 +59,8 @@ private slots:
|
||||
void on_pushButton_2_clicked();
|
||||
void on_pushButton_3_clicked();
|
||||
|
||||
void slotAsyncInstall(int t);
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
};
|
||||
|
@ -54,36 +54,42 @@ DownloadListWidget::~DownloadListWidget()
|
||||
{
|
||||
if (downloadController)
|
||||
{
|
||||
downloadController->disconnect();
|
||||
downloadController->stopDownload();
|
||||
downloadController->deleteLater();
|
||||
}
|
||||
|
||||
clearItem();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DownloadListWidget::clearItem()
|
||||
{
|
||||
ui->listWidget->vScrollBar->scrollTop();
|
||||
int n = ui->listWidget->count();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
QListWidgetItem *item = ui->listWidget->takeItem(0);
|
||||
QWidget *card = ui->listWidget->itemWidget(item);
|
||||
delete card;
|
||||
card = NULL;
|
||||
delete item;
|
||||
item = NULL;
|
||||
}
|
||||
// QListWidgetItem *item = nullptr;
|
||||
// while ((item = ui->listWidget->takeItem(0)) != nullptr)
|
||||
// {
|
||||
// QWidget *card = ui->listWidget->itemWidget(item);
|
||||
// if (card)
|
||||
// {
|
||||
// card->deleteLater();
|
||||
// card = nullptr;
|
||||
// }
|
||||
// delete item;
|
||||
// item = nullptr;
|
||||
// }
|
||||
|
||||
// ui->listWidget->vScrollBar->scrollTop();
|
||||
ui->listWidget->clear();
|
||||
}
|
||||
void DownloadListWidget::addItem(QString name, QString fileName, QString pkgName, const QPixmap icon, QString downloadurl)
|
||||
DownloadItem* DownloadListWidget::addItem(QString name, QString fileName, QString pkgName, const QPixmap icon, QString downloadurl)
|
||||
{
|
||||
if (fileName.isEmpty())
|
||||
{
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
urList.append(downloadurl);
|
||||
allDownload += 1;
|
||||
DownloadItem *di = new DownloadItem(this);
|
||||
DownloadItem *di = new DownloadItem;
|
||||
dlist << downloadurl;
|
||||
downloaditemlist << di;
|
||||
di->setName(name);
|
||||
@ -99,6 +105,8 @@ void DownloadListWidget::addItem(QString name, QString fileName, QString pkgName
|
||||
nowDownload += 1;
|
||||
startRequest(urList.at(nowDownload - 1), fileName); // 进行链接请求
|
||||
}
|
||||
|
||||
return di;
|
||||
}
|
||||
|
||||
QList<DownloadItem *> DownloadListWidget::getDIList()
|
||||
@ -119,7 +127,13 @@ void DownloadListWidget::startRequest(QUrl url, QString fileName)
|
||||
isdownload = true;
|
||||
downloaditemlist[allDownload - 1]->free = false;
|
||||
|
||||
downloadController = new DownloadController(this); // 并发下载,在点击下载按钮的时候才会初始化
|
||||
if (downloadController)
|
||||
{
|
||||
downloadController->disconnect();
|
||||
downloadController->stopDownload();
|
||||
downloadController->deleteLater();
|
||||
}
|
||||
downloadController = new DownloadController; // 并发下载,在点击下载按钮的时候才会初始化
|
||||
connect(downloadController, &DownloadController::downloadProcess, this, &DownloadListWidget::updateDataReadProgress);
|
||||
connect(downloadController, &DownloadController::downloadFinished, this, &DownloadListWidget::httpFinished);
|
||||
// connect(downloadController, &DownloadController::errorOccur, this, [=](QString msg){this->sendNotification(msg);});
|
||||
|
@ -20,7 +20,7 @@ class DownloadListWidget : public DBlurEffectWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void addItem(QString name, QString fileName, QString pkgName, const QPixmap icon, QString downloadurl);
|
||||
DownloadItem *addItem(QString name, QString fileName, QString pkgName, const QPixmap icon, QString downloadurl);
|
||||
int nowDownload = 0;
|
||||
int allDownload = 0;
|
||||
QList<DownloadItem *> getDIList();
|
||||
@ -35,7 +35,7 @@ private:
|
||||
QStringList dlist;
|
||||
QList<QUrl> urList;
|
||||
QList<DownloadItem *> downloaditemlist;
|
||||
DownloadController *downloadController;
|
||||
DownloadController *downloadController = nullptr;
|
||||
int nowdownload = 0;
|
||||
QString theSpeed;
|
||||
QTimer download_speed;
|
||||
|
Loading…
x
Reference in New Issue
Block a user