mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
[Network] and [Kernel] add Cancel for downloader (windows)
This commit is contained in:
@ -59,8 +59,8 @@ namespace NSNetwork
|
||||
m_sResponse = L"";
|
||||
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
m_func_onComplete = nullptr;
|
||||
m_func_onProgress = nullptr;
|
||||
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
@ -82,8 +82,8 @@ namespace NSNetwork
|
||||
m_sResponse = L"";
|
||||
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
m_func_onComplete = nullptr;
|
||||
m_func_onProgress = nullptr;
|
||||
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
@ -105,8 +105,8 @@ namespace NSNetwork
|
||||
m_sResponse = L"";
|
||||
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
m_func_onComplete = nullptr;
|
||||
m_func_onProgress = nullptr;
|
||||
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
@ -118,6 +118,7 @@ namespace NSNetwork
|
||||
NSFile::CFileBinary::Remove(m_sDownloadFilePath);
|
||||
m_sDownloadFilePath = L"";
|
||||
}
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
|
||||
virtual int DownloadFile() = 0;
|
||||
|
||||
@ -32,7 +32,6 @@
|
||||
|
||||
#include "FileTransporter_private.h"
|
||||
|
||||
|
||||
#include <wininet.h>
|
||||
#pragma comment(lib, "Wininet")
|
||||
#pragma comment(lib, "Ole32.lib")
|
||||
@ -90,8 +89,15 @@ namespace NSNetwork
|
||||
CoInitialize ( NULL );
|
||||
if ( /*S_OK != _DownloadFile ( m_sFileUrl )*/TRUE )
|
||||
{
|
||||
DeleteUrlCacheEntry(m_sDownloadFileUrl.c_str());
|
||||
HRESULT hrResultAll = DownloadFileAll(m_sDownloadFileUrl, m_sDownloadFilePath);
|
||||
|
||||
if(E_ABORT == hrResultAll && m_bIsExit->load())
|
||||
{
|
||||
//DeleteUrlCacheEntry(m_sDownloadFileUrl.c_str());
|
||||
CoUninitialize ();
|
||||
return hrResultAll;
|
||||
}
|
||||
if (S_OK != hrResultAll)
|
||||
{
|
||||
hrResultAll = (true == DownloadFilePS(m_sDownloadFileUrl, m_sDownloadFilePath)) ? S_OK : S_FALSE;
|
||||
@ -369,15 +375,11 @@ namespace NSNetwork
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
if(m_func_onProgress)
|
||||
{
|
||||
DownloadProgress progress;
|
||||
progress.func_onProgress = m_func_onProgress;
|
||||
// Скачиваем файл с возвратом процентов состояния
|
||||
return URLDownloadToFileW (NULL, sFileURL.c_str(), strFileOutput.c_str(), NULL, static_cast<IBindStatusCallback*>(&progress));
|
||||
}
|
||||
else
|
||||
return URLDownloadToFileW (NULL, sFileURL.c_str(), strFileOutput.c_str(), NULL, NULL);
|
||||
DownloadProgress progress;
|
||||
progress.bIsExit = m_bIsExit;
|
||||
progress.func_onProgress = m_func_onProgress;
|
||||
// Скачиваем файл с возвратом процентов состояния
|
||||
return URLDownloadToFileW (NULL, sFileURL.c_str(), strFileOutput.c_str(), NULL, static_cast<IBindStatusCallback*>(&progress));
|
||||
}
|
||||
|
||||
class DownloadProgress : public IBindStatusCallback {
|
||||
@ -415,6 +417,10 @@ namespace NSNetwork
|
||||
|
||||
virtual HRESULT __stdcall OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
|
||||
{
|
||||
if(bIsExit && bIsExit->load())
|
||||
{
|
||||
return E_ABORT;
|
||||
}
|
||||
if(ulProgressMax != 0)
|
||||
{
|
||||
int percent = static_cast<int>((100.0 * ulProgress) / ulProgressMax);
|
||||
@ -424,7 +430,8 @@ namespace NSNetwork
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::function<void(int)> func_onProgress;
|
||||
std::atomic<bool>* bIsExit = nullptr;
|
||||
std::function<void(int)> func_onProgress = nullptr;
|
||||
};
|
||||
|
||||
bool DownloadFilePS(const std::wstring& sFileURL, const std::wstring& strFileOutput)
|
||||
|
||||
@ -46,9 +46,7 @@
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
pid_t pid;
|
||||
std::atomic<bool>* m_isExit;
|
||||
{
|
||||
std::string wget_url_validate(const std::string& url)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
@ -63,8 +61,8 @@ namespace NSNetwork
|
||||
|
||||
int download_external(const std::wstring& sUrl, const std::wstring& sOutput, std::function<void(int)> func_onProgress, std::atomic<bool>* isExit)
|
||||
{
|
||||
pid_t pid;
|
||||
int nReturnCode = -1;
|
||||
m_isExit = isExit;
|
||||
std::string sUrlA = U_TO_UTF8(sUrl);
|
||||
//sUrlA =("\"" + sUrlA + "\"");
|
||||
std::string sOutputA = U_TO_UTF8(sOutput);
|
||||
@ -134,7 +132,7 @@ namespace NSNetwork
|
||||
|
||||
while (1)
|
||||
{
|
||||
if(m_isExit->load())
|
||||
if(isExit && isExit->load())
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
//while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
|
||||
@ -168,7 +166,7 @@ namespace NSNetwork
|
||||
int waitres;
|
||||
while (1) // wait for child to complete
|
||||
{
|
||||
if(m_isExit->load())
|
||||
if(isExit && isExit->load())
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
return nReturnCode;
|
||||
@ -222,7 +220,7 @@ namespace NSNetwork
|
||||
int waitres;
|
||||
while (1) // wait for child to complete
|
||||
{
|
||||
if(m_isExit->load())
|
||||
if(isExit && isExit->load())
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
return nReturnCode;
|
||||
|
||||
@ -155,7 +155,7 @@ namespace NSThreads
|
||||
m_lThreadPriority = 0;
|
||||
|
||||
m_bIsNeedDestroy = false;
|
||||
m_bIsExit = new std::atomic<bool>(false);
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
CBaseThread::~CBaseThread()
|
||||
{
|
||||
@ -172,7 +172,7 @@ namespace NSThreads
|
||||
|
||||
m_bRunThread = TRUE;
|
||||
|
||||
m_bIsExit->exchange(false);
|
||||
m_bIsExit = new std::atomic<bool>(false);
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
|
||||
DWORD dwTemp;
|
||||
((__native_thread*)m_hThread)->m_thread = CreateThread(NULL, 0, &__ThreadProc, (void*)this, 0, &dwTemp);
|
||||
@ -197,11 +197,13 @@ namespace NSThreads
|
||||
m_bRunThread = FALSE;
|
||||
|
||||
Join();
|
||||
RELEASEOBJECT(m_bIsExit);
|
||||
RELEASEOBJECT(m_hThread);
|
||||
}
|
||||
void CBaseThread::StopNoJoin()
|
||||
{
|
||||
m_bRunThread = FALSE;
|
||||
RELEASEOBJECT(m_bIsExit);
|
||||
RELEASEOBJECT(m_hThread);
|
||||
}
|
||||
void CBaseThread::DestroyOnFinish()
|
||||
@ -241,12 +243,10 @@ namespace NSThreads
|
||||
|
||||
m_bIsExit->exchange(true);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)
|
||||
//WaitForSingleObject(((__native_thread*)m_hThread)->m_thread, INFINITE);
|
||||
#else
|
||||
//pthread_cancel(((__native_thread*)m_hThread)->m_thread);
|
||||
//pthread_kill(((__native_thread*)m_hThread)->m_thread, SIGUSR1);
|
||||
pthread_join(((__native_thread*)m_hThread)->m_thread, 0);
|
||||
#endif
|
||||
m_bRunThread = FALSE;
|
||||
|
||||
Join();
|
||||
RELEASEOBJECT(m_bIsExit);
|
||||
RELEASEOBJECT(m_hThread);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ namespace NSThreads
|
||||
class KERNEL_DECL CBaseThread
|
||||
{
|
||||
protected:
|
||||
CThreadDescriptor* m_hThread;
|
||||
CThreadDescriptor* m_hThread;
|
||||
INT m_bRunThread;
|
||||
INT m_bSuspend;
|
||||
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
QT -= gui
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += c++11 console
|
||||
CONFIG -= app_bundle
|
||||
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
include(TestDownloader.pri)
|
||||
|
||||
SOURCES += \
|
||||
main.cpp
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2014-10-03T18:30:31
|
||||
#
|
||||
#-------------------------------------------------
|
||||
QT += core gui
|
||||
|
||||
QT -= core
|
||||
QT -= gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CORE_ROOT_DIR = $$PWD/../../..
|
||||
CONFIG += c++11
|
||||
#CONFIG += console
|
||||
|
||||
CORE_ROOT_DIR = $$PWD/../../../../core
|
||||
PWD_ROOT_DIR = $$PWD
|
||||
|
||||
include(../../../Common/base.pri)
|
||||
include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
|
||||
core_windows {
|
||||
QMAKE_LFLAGS += /INCREMENTAL:NO
|
||||
@ -21,8 +19,9 @@ core_windows {
|
||||
DEFINES += KERNEL_USE_DYNAMIC_LIBRARY
|
||||
|
||||
core_windows {
|
||||
DEFINES += _RWSTD_NO_SETRLIMIT
|
||||
DEFINES += _RWSTD_NO_SETRLIMIT
|
||||
}
|
||||
|
||||
#CORE_BUILDS_LIBRARIES_PATH = $$CORE_ROOT_DIR/build/lib/linux_64/debug #linux
|
||||
CORE_BUILDS_LIBRARIES_PATH = $$CORE_ROOT_DIR/build/lib/win_64/debug #windows
|
||||
#kernel
|
||||
@ -36,10 +35,26 @@ LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lkernel_network
|
||||
|
||||
#BOOST
|
||||
CONFIG += core_boost_regex
|
||||
include($$PWD/../../../Common/3dParty/boost/boost.pri)
|
||||
include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri)
|
||||
|
||||
core_windows {
|
||||
LIBS += -lAdvapi32
|
||||
}
|
||||
########################################################
|
||||
|
||||
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
@ -1,17 +1,11 @@
|
||||
#include "../../../Common/Network/FileTransporter/include/FileTransporter.h"
|
||||
#define CHECK_URL L"http://download.onlyoffice.com/install/desktop/editors/windows/onlyoffice/updates/editors_update_x64.exe"
|
||||
typedef NSNetwork::NSFileTransport::CFileDownloader Downloader;
|
||||
#include <vector>
|
||||
//int wmain(int argc, wchar_t *argv[]) windows
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
auto check_url = CHECK_URL;
|
||||
auto downloader = new Downloader(check_url, false);
|
||||
std::vector<int> vec;
|
||||
downloader->SetEvent_OnProgress([&](int percent) {
|
||||
vec.push_back(percent);
|
||||
});
|
||||
downloader->SetFilePath(L"/mnt/HDD_DATA/Work/core/Test/Applications/TestDownloader/tmp.exe");
|
||||
//downloader->SetFilePath(L"C:\\Users\\Vladimir.Gorshenkov\\Downloads\\tmp.exe"); windows
|
||||
downloader->DownloadSync();
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
79
Test/Applications/TestDownloader/mainwindow.cpp
Normal file
79
Test/Applications/TestDownloader/mainwindow.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
#define URL L"http://download.onlyoffice.com/install/desktop/editors/windows/onlyoffice/updates/editors_update_x64.exe"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent):
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
downloader = new Downloader(URL, false);
|
||||
downloader->SetEvent_OnComplete(std::bind(&MainWindow::onLoadUpdateFinished, this, std::placeholders::_1));
|
||||
downloader->SetEvent_OnProgress(std::bind(&MainWindow::onProgress, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete downloader;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::onProgress(const int percent)
|
||||
{
|
||||
qDebug() << "Precent... " << percent;
|
||||
QMetaObject::invokeMethod(this, "onProgressSlot", Qt::QueuedConnection, Q_ARG(int, percent));
|
||||
}
|
||||
|
||||
void MainWindow::onProgressSlot(int percent)
|
||||
{
|
||||
ui->textEdit->setText(QString::number(percent));
|
||||
ui->progressBar->setValue(percent);
|
||||
}
|
||||
|
||||
void MainWindow::onLoadUpdateFinished(int error)
|
||||
{
|
||||
qDebug() << "Loading finished...";
|
||||
QMetaObject::invokeMethod(this, "onLoadFinishedSlot", Qt::QueuedConnection, Q_ARG(int, error));
|
||||
}
|
||||
|
||||
void MainWindow::onLoadFinishedSlot(int error)
|
||||
{
|
||||
if (error == 0) {
|
||||
ui->textEdit->setText("Loading finished...");
|
||||
} else {
|
||||
qDebug() << "Download error: " << error;
|
||||
ui->textEdit->setText("Download error");
|
||||
}
|
||||
|
||||
const QString path = QString::fromStdWString(downloader->GetFilePath());
|
||||
if (QDir().exists(path)) QDir().remove(path);
|
||||
}
|
||||
|
||||
void MainWindow::on_buttonStart_clicked()
|
||||
{
|
||||
qDebug() << "Start loading...";
|
||||
ui->progressBar->setValue(0);
|
||||
// const QString tmp_file = QDir::tempPath() + QDir::separator() + QString("temp.tmp");
|
||||
const QString tmp_file = QString("C:\\Users\\Vladimir.Gorshenkov\\NewControl\\core\\Test\\Applications\\TestDownloader\\temp.tmp");
|
||||
ui->textEdit->setText(QString("Start loading: %1 to %2").arg(QString::fromStdWString(URL), tmp_file));
|
||||
downloader->SetFilePath(tmp_file.toStdWString());
|
||||
downloader->Start(0);
|
||||
}
|
||||
|
||||
void MainWindow::on_buttonCancel_clicked()
|
||||
{
|
||||
qDebug() << "Loading cancel...";
|
||||
ui->progressBar->setValue(0);
|
||||
ui->textEdit->setText("Loading cancel...");
|
||||
const QString path = QString::fromStdWString(downloader->GetFilePath());
|
||||
downloader->Cancel();
|
||||
// if (QDir().exists(path)) QDir().remove(path);
|
||||
|
||||
qDebug() << "Stop finished";
|
||||
}
|
||||
|
||||
|
||||
46
Test/Applications/TestDownloader/mainwindow.h
Normal file
46
Test/Applications/TestDownloader/mainwindow.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include "../../../../core/Common/Network/FileTransporter/include/FileTransporter.h"
|
||||
|
||||
|
||||
//#define URL L"http://nct.onlyoffice.com/sh/XHh"
|
||||
typedef std::wstring WString;
|
||||
typedef NSNetwork::NSFileTransport::CFileDownloader Downloader;
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {class MainWindow;}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
|
||||
void on_buttonStart_clicked();
|
||||
void on_buttonCancel_clicked();
|
||||
|
||||
void onProgressSlot(int percent);
|
||||
void onLoadFinishedSlot(int error);
|
||||
|
||||
private:
|
||||
|
||||
void onProgress(const int percent);
|
||||
void onLoadUpdateFinished(int error);
|
||||
|
||||
Downloader *downloader;
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
62
Test/Applications/TestDownloader/mainwindow.ui
Normal file
62
Test/Applications/TestDownloader/mainwindow.ui
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>616</width>
|
||||
<height>479</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="buttonStart">
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QPushButton" name="buttonCancel">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>616</width>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user