uengine-runner/Android X86/AXVM/downloadthread.cpp

197 lines
6.8 KiB
C++
Raw Normal View History

2022-08-11 12:27:25 +08:00
#define SETTINGSTEP 6
2022-08-03 22:59:13 +08:00
#include "downloadthread.h"
#include <QProgressDialog>
#include <QFile>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QEventLoop>
#include <QTimer>
#include <QNetworkReply>
#include <QMessageBox>
2022-08-11 12:27:25 +08:00
#include <QCoreApplication>
// 文件操作
#include <QDir>
// 命令执行
#include <QProcess>
// 获取内存总量
#if defined(Q_OS_LINUX) // 区分系统平台
#include "sys/statfs.h" // Linux 上
#else // Windows 上
#pragma comment(lib, "Kernel32.lib")
#pragma comment(lib, "Psapi.lib")
#include <windows.h>
#include <tlhelp32.h>
#endif
2022-08-03 22:59:13 +08:00
2022-08-11 12:27:25 +08:00
DownloadThread::DownloadThread(QProgressDialog *progressDialog, QString url, QString name, QString mouse, bool NotDownload){
2022-08-03 22:59:13 +08:00
dialog = progressDialog;
fileUrl = url;
2022-08-11 12:27:25 +08:00
vmName = name;
setMouse = mouse;
notDownload = NotDownload;
2022-08-03 22:59:13 +08:00
}
// 文件下载
void DownloadThread::run(){
2022-08-11 12:27:25 +08:00
// 创建文件夹
QDir dir;
QString configDir = QCoreApplication::applicationDirPath() + "/VM";
if(!dir.exists(configDir)){
// 文件不存在
dir.mkpath(configDir);
}
configDir = QCoreApplication::applicationDirPath() + "/VM/" + vmName;
if(!dir.exists(configDir)){
// 文件不存在
dir.mkpath(configDir);
}
QString savePath = configDir + "/vm.ova";
// 文件下载
2022-08-03 22:59:13 +08:00
int timeout = 0;
QFile f(savePath);
if(!f.open(QIODevice::WriteOnly)){
2022-08-11 12:27:25 +08:00
emit MessageBoxError("文件无法写入");
f.close();
delete dialog;
dialog->close();
return;
}
if(notDownload){
qDebug() << "b";
SettingVirtualMachine(savePath);
return;
2022-08-03 22:59:13 +08:00
}
QNetworkAccessManager m;
QNetworkRequest req;
2022-08-11 12:27:25 +08:00
// 响应 https就是不行
2022-08-20 13:38:46 +08:00
//QSslConfiguration conf = req.sslConfiguration();
//conf.setPeerVerifyMode(QSslSocket::VerifyNone);
//conf.setProtocol(QSsl::TlsV1_1);
//req.setSslConfiguration(conf);
req.setUrl(QUrl("https://code.gitlink.org.cn/gfdgd_xi/wine-mirrors/raw/branch/master/spark-wine7-devel-7.14.7z"));
2022-08-11 12:27:25 +08:00
// 下载文件
2022-08-03 22:59:13 +08:00
QNetworkReply *reply = m.get(req);
QEventLoop loop;
QTimer t;
qDebug() << reply->rawHeader(QString("Content-Length").toUtf8());
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
connect(reply, &QNetworkReply::downloadProgress, [=, &f, &t](qint64 bytesRead, qint64 totalBytes){
f.write(reply->readAll());
2022-08-11 12:27:25 +08:00
dialog->setValue((float)bytesRead / totalBytes * 100);
dialog->setLabelText(QString::number(bytesRead / 1024 / 1024) + "MB/" + QString::number(totalBytes / 1024 / 1024) + "MB");
2022-08-03 22:59:13 +08:00
if(t.isActive()){
t.start(timeout);
}
});
if(timeout > 0){
connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit);
t.start(timeout);
}
loop.exec();
if(reply->error() != QNetworkReply::NoError){
2022-08-11 12:27:25 +08:00
emit MessageBoxError("下载失败");
f.close();
delete reply;
delete dialog;
dialog->close();
return;
2022-08-03 22:59:13 +08:00
}
f.close();
delete reply;
2022-08-11 12:27:25 +08:00
SettingVirtualMachine(savePath);
}
void DownloadThread::SettingVirtualMachine(QString savePath){
// 设置虚拟机
dialog->setLabelText("设置虚拟机");
dialog->setWindowTitle("正在设置“" + vmName + "");
dialog->setValue(100 / SETTINGSTEP * 0);
dialog->show();
// 拷贝 OVA 文件
if(notDownload){
if(QFile::exists(savePath)){
QFile::remove(savePath);
}
if(!QFile::copy(fileUrl, savePath)){
emit MessageBoxError("文件复制错误,无法继续");
}
}
// 导入 OVA 镜像
QProcess progress;
QStringList command;
dialog->setValue(100 / SETTINGSTEP * 1);
command << "import" << savePath;
progress.start("VBoxManage", command);
progress.waitForFinished();
qDebug() << "正常信息:\n";
qDebug() << progress.readAllStandardOutput();
qDebug() << "错误信息:\n";
qDebug() << progress.readAllStandardError();
// 获取内存
dialog->setValue(100 / SETTINGSTEP * 2);
int memtotal = 0;
#if defined (Q_OS_LINUX) // 在 Linux 下读取总内存
progress.start("free -m");
progress.waitForFinished();
progress.readLine(); // 忽略第一行
QString memoryInfo = progress.readLine(); // 只读取第 2 行
qDebug() << memoryInfo;
memoryInfo.replace("\n", ""); // 忽略换行符
memoryInfo.replace(QRegExp("( ){1,}"), " "); // 将连续的空格换为单个空格
auto memoryList = memoryInfo.split(" "); // 根据空格切割内容
qDebug() << memoryList;
if(memoryList.size() >= 2){ // 保证至少有两个
// 理论上列表应该出现的是如下的内容
// ["Mem:", "13998", "9622", "197", "803", "4179", "3331"]
// 因此要读[1]
memtotal = memoryList[1].toDouble();
}
else{
emit MessageBoxError("内存读取错误,请自行打开 VirtualBox 设置内存");
return;
}
#endif
// 设置内存
// 示例命令VBoxManage modifyvm [name] --memory 4096
command.clear(); // 清空参数列表
command << "modifyvm" << vmName << "--memory" << QString::number(memtotal / 2);
progress.start("VBoxManage", command);
progress.waitForFinished();
// 设置显卡,默认的 VMSVGA 在 Android X86 上运行有很多问题,应设为 VBoxVGA
// 示例命令VBoxManage modifyvm [name] --graphicscontroller vboxvga
dialog->setValue(100 / SETTINGSTEP * 3);
command.clear(); // 清空参数列表
command << "modifyvm" << vmName << "--graphicscontroller" << "vboxvga";
qDebug() << command;
progress.start("VBoxManage", command);
progress.waitForFinished();
// 设置声卡
// VBoxManage modifyvm [name] --audio pulse --audiocontroller hda --audioin on --audioout on
dialog->setValue(100 / SETTINGSTEP * 4);
command.clear(); // 清空参数列表
command << "modifyvm" << vmName << "--audio" << "pulse" << "--audiocontroller" << "hda" << "--audioin" << "on" << "--audioout" << "on";
progress.start("VBoxManage", command);
progress.waitForFinished();
// 设置显存
// VBoxManage modifyvm [name] --vram 128
dialog->setValue(100 / SETTINGSTEP * 5);
command.clear(); // 清空参数列表
command << "modifyvm" << vmName << "--vram" << "128";
progress.start("VBoxManage", command);
progress.waitForFinished();
// 设置鼠标
// VBoxManage modifyvm [name] --mouse ps2
dialog->setValue(100 / SETTINGSTEP * 6);
if(setMouse == "ps2"){
command.clear(); // 清空参数列表
command << "modifyvm" << vmName << "--mouse" << "ps2";
progress.start("VBoxManage", command);
progress.waitForFinished();
}
// 结束
dialog->setValue(100);
emit MessageBoxOpenVM(vmName);
2022-08-03 22:59:13 +08:00
dialog->close();
2022-08-11 12:27:25 +08:00
delete dialog;
2022-08-03 22:59:13 +08:00
}