@@ -470,47 +470,23 @@ PluginFinishType CliInterface::addFiles(const QList<FileEntry> &files, const Com
470470 QFileInfo (m_strArchiveName).path (),
471471 sRenameList );
472472
473- if (options.bTar_7z ) { // 压缩tar.7z:用两个 QProcess 管道,避免 shell 拼接与密码特殊字符问题
473+ if (options.bTar_7z ) { // 压缩tar.7z文件
474474 m_isTar7z = true ;
475- m_filesSize = options.qTotalSize ;
476- const QString archivePath = temp_archiveName.isEmpty () ? m_strArchiveName : temp_archiveName;
477- QStringList tarArgs = m_cliProps->getTar7zTarArgs (fileList, sRenameList );
478- QStringList sevenZArgs = m_cliProps->getTar7z7zArgs (archivePath, password, options.bHeaderEncryption ,
479- options.iCompressionLevel , options.strCompressionMethod ,
480- options.strEncryptionMethod , options.iVolumeSize );
481- QString tarPath = QStandardPaths::findExecutable (QStringLiteral (" tar" ));
482- QString sevenZPath = QStandardPaths::findExecutable (m_cliProps->property (" addProgram" ).toString ());
483- if (tarPath.isEmpty () || sevenZPath.isEmpty ()) {
484- ret = false ;
485- } else {
486- m_tar7z_7z = new QProcess ();
487- m_tarProcess = new QProcess ();
488- m_tarProcess->setStandardOutputProcess (m_tar7z_7z);
489- m_tar7z_7z->setProcessChannelMode (QProcess::MergedChannels);
490- connect (m_tar7z_7z, &QProcess::readyReadStandardOutput, this , [this ]() { readStdout (); });
491- connect (m_tar7z_7z, QOverload<int , QProcess::ExitStatus>::of (&QProcess::finished), this , &CliInterface::processFinished);
492- m_stdOutData.clear ();
493- m_isProcessKilled = false ;
494- m_tarProcess->start (tarPath, tarArgs);
495- if (m_tarProcess->waitForStarted (5000 )) {
496- m_tar7z_7z->start (sevenZPath, sevenZArgs);
497- // 不在此处 waitForStarted(7z),避免 7z 等 stdin 时阻塞主线程导致卡死
498- ret = m_tar7z_7z->state () == QProcess::Starting || m_tar7z_7z->state () == QProcess::Running;
499- if (ret) {
500- m_processId = m_tar7z_7z->processId ();
501- m_childProcessId = QVector<qint64>() << m_tarProcess->processId ();
502- }
503- connect (m_tar7z_7z, &QProcess::errorOccurred, this , [this ](QProcess::ProcessError) {
504- if (m_tar7z_7z && m_tar7z_7z->state () == QProcess::NotRunning) {
505- processFinished (-1 , QProcess::CrashExit);
506- }
507- });
508- } else {
509- ret = false ;
510- }
511- if (!ret) {
512- deleteProcess ();
475+ m_filesSize = options.qTotalSize ; // 待压缩文件总大小
476+ m_scriptPath = QDir::tempPath () + " /tempScript_" + QString::number (QDateTime::currentDateTime ().toMSecsSinceEpoch ()) + " .sh" ;
477+ QFile scriptFile (m_scriptPath);
478+ if (scriptFile.open (QIODevice::WriteOnly | QIODevice::Text)) {
479+ QTextStream out (&scriptFile);
480+ out << " #!/bin/bash\n " ;
481+ for (const QString &arg : arguments) {
482+ out << arg << " \n " ;
513483 }
484+ scriptFile.close ();
485+ QProcess::execute (" chmod" , { " +x" , m_scriptPath });
486+ ret = runProcess (m_scriptPath, QStringList ());
487+ } else {
488+ qWarning () << " Failed to create temporary script file." ;
489+ ret = false ;
514490 }
515491 } else {
516492 QString processName = m_cliProps->property (" addProgram" ).toString ();
@@ -531,11 +507,7 @@ PluginFinishType CliInterface::addFiles(const QList<FileEntry> &files, const Com
531507 qInfo () << " mtp 压缩完成,现在开始移动" ;
532508 QStringList args_list;
533509 args_list << temp_archiveName << m_strArchiveName;
534- if (m_tar7z_7z) {
535- m_tar7z_7z->waitForFinished (-1 );
536- } else if (m_process) {
537- m_process->waitForFinished ();
538- }
510+ m_process->waitForFinished ();
539511 QProcess mover;
540512 ret = 0 == mover.execute (" mv" , args_list);
541513 ret = mover.exitCode () == QProcess::NormalExit;
@@ -823,53 +795,22 @@ bool CliInterface::runProcess(const QString &programName, const QStringList &arg
823795 return true ;
824796}
825797
826- bool CliInterface::killTar7zPipelineIfActive ()
827- {
828- if (!m_tar7z_7z) {
829- return false ;
830- }
831- if (m_tarProcess && m_tarProcess->state () != QProcess::NotRunning) {
832- m_tarProcess->kill ();
833- }
834- if (m_tar7z_7z->state () != QProcess::NotRunning) {
835- m_tar7z_7z->kill ();
836- }
837- m_isProcessKilled = true ;
838- return true ;
839- }
840-
841798void CliInterface::deleteProcess ()
842799{
843- if (m_tar7z_7z) {
844- m_tar7z_7z->blockSignals (true );
845- if (m_tar7z_7z->state () != QProcess::NotRunning) {
846- m_tar7z_7z->kill ();
847- m_tar7z_7z->waitForFinished (500 );
848- }
849- delete m_tar7z_7z;
850- m_tar7z_7z = nullptr ;
851- if (m_tarProcess) {
852- m_tarProcess->blockSignals (true );
853- if (m_tarProcess->state () != QProcess::NotRunning) {
854- m_tarProcess->kill ();
855- m_tarProcess->waitForFinished (500 );
856- }
857- delete m_tarProcess;
858- m_tarProcess = nullptr ;
859- }
860- return ;
861- }
862800 if (m_process) {
863801 readStdout (true );
864802 m_process->blockSignals (true ); // delete m_process之前需要断开所有m_process信号,防止重复处理
865803 delete m_process;
866804 m_process = nullptr ;
805+ if (!m_scriptPath.isEmpty ()) {
806+ QFile::remove (m_scriptPath);
807+ }
867808 }
868809}
869810
870811void CliInterface::handleProgress (const QString &line)
871812{
872- if (m_tar7z_7z || ( m_process && m_process->program ().at (0 ).contains (" 7z" ))) { // 解析7z相关进度、文件名(含 tar.7z 管道)
813+ if (m_process && m_process->program ().at (0 ).contains (" 7z" )) { // 解析7z相关进度、文件名
873814 int pos = line.indexOf (QLatin1Char (' %' ));
874815 if (pos > 1 ) {
875816 int percentage = line.midRef (pos - 3 , 3 ).toInt ();
@@ -963,6 +904,29 @@ void CliInterface::handleProgress(const QString &line)
963904
964905 emit signalCurFileName (fileName);
965906 }
907+ } else if (m_process && m_process->program ().at (0 ).contains (" tempScript" )) {
908+ // 处理tar.7z进度
909+ // "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b 7M + [Content]"
910+ // "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b274M 1 + [Content]"
911+ int pos = line.lastIndexOf (" + [Content]" );
912+ if (pos > 1 ) {
913+ int mPos = line.lastIndexOf (" M " );
914+ int bPos = line.lastIndexOf (" \b " , mPos );
915+ QString tempLine = line.left (mPos );
916+ // 已经压缩的文件大小
917+ qint64 compressedSize = tempLine.right (tempLine.size () - bPos - 1 ).toLongLong ();
918+ // 计算文件大小计算百分比
919+ qint64 percentage = compressedSize * 1024 * 1024 * 100 / m_filesSize;
920+
921+ emit signalprogress (percentage);
922+ // tar.7z 无法获取正在压缩的单个文件名,但可以提示正在打包成 tar 文件
923+ // 发送 tar 文件名提示(去掉 .7z 后缀,显示正在打包的 tar 文件名)
924+ QString tarFileName = QFileInfo (m_strArchiveName).fileName ();
925+ if (tarFileName.endsWith (" .7z" , Qt::CaseInsensitive)) {
926+ tarFileName = tarFileName.left (tarFileName.length () - 3 );
927+ }
928+ emit signalCurFileName (tarFileName);
929+ }
966930 }
967931}
968932
@@ -1072,14 +1036,9 @@ PluginFinishType CliInterface::handleCorrupt()
10721036
10731037void CliInterface::writeToProcess (const QByteArray &data)
10741038{
1039+ Q_ASSERT (m_process);
10751040 Q_ASSERT (!data.isNull ());
1076- // tar.7z 管道下 stdin 为 tar 输出,不能写入,密码已通过命令行传入
1077- if (m_tar7z_7z) {
1078- return ;
1079- }
1080- if (!m_process) {
1081- return ;
1082- }
1041+
10831042 // m_process->write(data);
10841043 m_process->pty ()->write (data);
10851044}
@@ -1336,17 +1295,14 @@ void CliInterface::readStdout(bool handleAll)
13361295 return ;
13371296 }
13381297
1339- QProcess *outProcess = m_tar7z_7z ? m_tar7z_7z : m_process;
1340- if (!outProcess) {
1341- return ;
1342- }
1298+ Q_ASSERT (m_process);
13431299
1344- if (!outProcess ->bytesAvailable ()) { // 无数据
1300+ if (!m_process ->bytesAvailable ()) { // 无数据
13451301 return ;
13461302 }
13471303
13481304 // 获取命令行输出
1349- QByteArray dd = outProcess ->readAllStandardOutput ();
1305+ QByteArray dd = m_process ->readAllStandardOutput ();
13501306 m_stdOutData += dd;
13511307
13521308 // 换行分割
@@ -1358,10 +1314,12 @@ void CliInterface::readStdout(bool handleAll)
13581314 // }
13591315 bool isWrongPwd = isWrongPasswordMsg (lines.last ());
13601316
1361- // 7z 或 tar.7z 管道:进度行结束无 \n
1362- bool is7zAdd = m_tar7z_7z || (m_process && m_process->program ().at (0 ).contains (" 7z" ) && m_process->program ().at (1 ) != " l" );
1363- if (is7zAdd && !isWrongPwd) {
1364- handleAll = true ;
1317+ if ((m_process->program ().at (0 ).contains (" 7z" ) && m_process->program ().at (1 ) != " l" ) && !isWrongPwd) {
1318+ handleAll = true ; // 7z进度行结束无\n
1319+ }
1320+
1321+ if ((m_process->program ().at (0 ).contains (" tempScript" )) && !isWrongPwd) {
1322+ handleAll = true ; // compress .tar.7z progressline has no \n
13651323 }
13661324
13671325 bool foundErrorMessage = (isWrongPwd || isDiskFullMsg (QLatin1String (lines.last ()))
@@ -1378,7 +1336,7 @@ void CliInterface::readStdout(bool handleAll)
13781336 // because the last line might be incomplete we leave it for now
13791337 // note, this last line may be an empty string if the stdoutdata ends
13801338 // with a newline
1381- if (m_process && m_process ->program ().at (0 ).contains (" unrar" )) { // 针对unrar的命令行截取
1339+ if (m_process->program ().at (0 ).contains (" unrar" )) { // 针对unrar的命令行截取
13821340 m_stdOutData.clear ();
13831341 if (lines.count () > 0 ) {
13841342 if (!(lines[lines.count () - 1 ].endsWith (" %" ) || lines[lines.count () - 1 ].endsWith (" OK " ))) {
0 commit comments