[win-linux] updmanager: add display of unpacking progress

This commit is contained in:
SimplestStudio
2024-01-10 09:15:17 +02:00
parent 562ba59476
commit 730e008534
8 changed files with 94 additions and 2 deletions

View File

@ -66,6 +66,7 @@ enum MsgCommands {
MSG_StartReplacingFiles,
MSG_ClearTempFiles,
MSG_Progress,
MSG_UnzipProgress,
MSG_StopDownload,
MSG_OtherError,
MSG_SetLanguage,

View File

@ -224,6 +224,9 @@ void CSvcManager::init()
m_pUnzip->onComplete([=](int error) {
onCompleteUnzip(error);
});
m_pUnzip->onProgress([=](int percent) {
m_socket->sendMessage(MSG_UnzipProgress, to_tstring(percent));
});
m_socket->onMessageReceived([=](void *data, size_t) {
vector<tstring> params;
if (m_socket->parseMessage(data, params) == 3) {

View File

@ -34,6 +34,7 @@
#include "platform_linux/utils.h"
#include <archive.h>
#include <archive_entry.h>
#include <sys/stat.h>
#include <cstring>
#define BLOCK_SIZE 10240
@ -53,6 +54,10 @@ public:
error = "Archive path is empty or dest dir not exist";
return UNZIP_ERROR;
}
int prev_percent = -1;
struct stat file_stat;
long total_size = (stat(zipFilePath.c_str(), &file_stat) == 0) ? file_stat.st_size : 0;
struct archive *arch = archive_read_new();
archive_read_support_filter_xz(arch);
archive_read_support_format_tar(arch);
@ -89,6 +94,13 @@ public:
error = "Cannot extract entry";
break;
}
if (total_size > 0 && progress_callback) {
int percent = static_cast<int>(100.0 * ((double)archive_filter_bytes(arch, -1)/total_size));
if (percent != prev_percent) {
progress_callback(percent);
prev_percent = percent;
}
}
}
}
@ -102,7 +114,8 @@ public:
return ex_code;
}
FnVoidInt complete_callback = nullptr;
FnVoidInt complete_callback = nullptr,
progress_callback = nullptr;
std::atomic_bool run;
std::future<void> future;
};
@ -148,3 +161,8 @@ void CUnzip::onComplete(FnVoidInt callback)
{
pimpl->complete_callback = callback;
}
void CUnzip::onProgress(FnVoidInt callback)
{
pimpl->progress_callback = callback;
}

View File

@ -57,6 +57,7 @@ public:
/* callback */
void onComplete(FnVoidInt callback);
void onProgress(FnVoidInt callback);
private:
class CUnzipPrivate;

View File

@ -44,6 +44,40 @@ public:
~CUnzipPrivate()
{}
bool calcFilesCountRecursively(IShellDispatch *pISD, const CComPtr<Folder> &pSrcFolder)
{
CComPtr<FolderItems> pItems;
if (FAILED(pSrcFolder->Items(&pItems)))
return false;
long itemCount = 0;
if (FAILED(pItems->get_Count(&itemCount)))
return false;
for (int i = 0; i < itemCount; i++) {
CComPtr<FolderItem> pItem;
if (FAILED(pItems->Item(CComVariant(i), &pItem)))
return false;
VARIANT_BOOL isFolder = VARIANT_FALSE;
if (FAILED(pItem->get_IsFolder(&isFolder)))
return false;
if (isFolder == VARIANT_TRUE) {
CComPtr<Folder> pSubFolder;
if (FAILED(pISD->NameSpace(CComVariant(pItem), &pSubFolder)))
return false;
if (!calcFilesCountRecursively(pISD, pSubFolder))
return false;
} else {
++total_count;
}
}
return true;
}
int extractRecursively(IShellDispatch *pISD, const CComPtr<Folder> &pSrcFolder, const wstring &destFolder)
{
CComPtr<FolderItems> pItems;
@ -92,6 +126,14 @@ public:
return UNZIP_ERROR;
if (FAILED(pDestFolder->CopyHere(CComVariant(pItem), CComVariant(1024 | 512 | 16 | 4))))
return UNZIP_ERROR;
if (total_count > 0 && progress_callback) {
++curr_count;
int percent = static_cast<int>(100.0 * ((double)curr_count / total_count));
if (percent != prev_percent) {
progress_callback(percent);
prev_percent = percent;
}
}
}
}
return UNZIP_OK;
@ -122,6 +164,12 @@ public:
CoUninitialize();
return UNZIP_ERROR;
}
prev_percent = -1;
curr_count = 0;
total_count = 0;
if (!calcFilesCountRecursively(pShell, pSrcFolder))
total_count = 0;
int res = extractRecursively(pShell, pSrcFolder, path);
pSrcFolder.Release();
pShell->Release();
@ -129,9 +177,13 @@ public:
return res;
}
FnVoidInt complete_callback = nullptr;
FnVoidInt complete_callback = nullptr,
progress_callback = nullptr;
std::atomic_bool run;
std::future<void> future;
int curr_count = 0,
total_count = 0,
prev_percent = -1;
};
CUnzip::CUnzip() :
@ -170,3 +222,8 @@ void CUnzip::onComplete(FnVoidInt callback)
{
pimpl->complete_callback = callback;
}
void CUnzip::onProgress(FnVoidInt callback)
{
pimpl->progress_callback = callback;
}

View File

@ -57,6 +57,7 @@ public:
/* callback */
void onComplete(FnVoidInt callback);
void onProgress(FnVoidInt callback);
private:
class CUnzipPrivate;