Inno скрипт скачать файл из интернета Async - PullRequest
1 голос
/ 27 июля 2011

как я могу скачать файл из интернета в Inno. но учтите, что я хочу асинхронную загрузку. Другими словами, я хотел бы, чтобы загрузка начиналась в фоновом режиме, а пользовательский интерфейс был бы отзывчивым.

Насколько я знаю, не похоже, что есть какой-либо метод для загрузки асинхронного сценария inno, поскольку он не поддерживает тэды и таймер.

Не могли бы вы помочь мне с этим или сообщить мне другой способ достижения этого?

Ответы [ 3 ]

2 голосов
/ 27 июля 2011

Посмотрите на Загрузчик InnoTools . Он был написан именно для этой цели и дает прогресс загрузки и т. Д.

1 голос
/ 14 декабря 2017

Похоже, что InnoTools Downloader давно не обновлялся и не поддерживает UNICODE ...

Есть еще один перспективный проект: https://bitbucket.org/mitrich_k/inno-download-plugin Он был обновлен в декабре 2016и поддерживает ANSI и UNICODE версии InnoSetup.У него есть примеры и документация в порядке, он даже поддерживает несколько языков, таких как испанский, китайский язык ...

1 голос
/ 27 июля 2011

Я не уверен, что это можно сделать.Возможно, вы сможете написать DLL расширения с двумя функциями:

Одна, которая порождает новый поток для загрузки (передача URL-адреса загрузки и временное имя файла), и другую, которую вы можете регулярно вызывать, чтобы проверить,загрузка завершена или произошла ошибка.

Затем вы вызвали бы первую функцию при запуске вашей установки (убедитесь, что вы не запускаете загрузку при удалении).Вызвать второй метод, когда вам требуется загруженный файл.В какой-то момент вам нужно будет дождаться окончания загрузки.

Также, подумав об этом, будет полезна еще одна функция для отмены потока загрузки, чтобы вы могли реагировать на отмену установки.

См. этот вопрос , чтобы найти подсказки о том, как вызвать функцию в DLL из скрипта Pascal.

РЕДАКТИРОВАТЬ
Чтобы было более понятно, чтоЯ ожидаю, что функции будут работать, я пытаюсь создать некоторый псевдокод (может выглядеть немного как C # ;-)):

// This is a global variable for the thread
Thread globalDownloadThread = null;
bool threadFinished = false;
bool threadShouldFinish = false;

void StartDownload(string url, string outputFile)
{
   globalDownloadThread = new Thread(DownloadThreadMethod);
   globalDownloadThread.Start(url, outputFile);
}

void DownloadThreadMethod(string url, string outputFile)
{
   bool downloadComplete = false;
   bool downloadErrors = false;

   while (!threadShouldFinish && !downloadComplete && !downloadErrors)
   {
       // Download a bit of the file
       // Save to the output file

       // Store errors
       if (error)
          downloadErrors = true;
       else if (noMoreBytesToDownload)
          // When we're done...
          downloadComplete = true;
   }

   threadFinished = true;
 }

 void CancelThread()
 {
   threadShouldFinish = true;
   globalDownloadThread.Join(); // Wait for thread to finish!
 }

 bool IsThreadDone()
 {
   return threadFinished;
 }

В Inno Setup, вызовите StartDownloadМетод первый.Если настройка отменяется после вызова StartDownload (только тогда есть поток!), Позвоните CancelThread.

В тот момент, когда вам нужно убедиться, что файл был загружен, повторно позвоните IsThreadDone пока он не вернет истину.

Конечно, это должно быть приправлено механизмами блокировки, и здесь нет реальных сообщений об ошибках, но я надеюсь, что вы получите представление о том, что я имел в виду.

РЕДАКТИРОВАТЬ 2
Я переведу часть моего псевдокода на C ++ из того, что вы опубликовали в комментариях.

HANDLE hThread = 0;
DWORD dwThreadId = 0;
DWORD dwThreadResult = 0;

extern "C" bool _declspec(dllexport) downloadfile(TCHAR *url, TCHAR *dest) 
{ 
    DOWNLOADPARAM *obj = new DOWNLOADPARAM(); 
    obj->szURL = url; 
    obj->szFilePath = dest; 

    if ((hThread = CreateThread(NULL, 0, inetTransfer, (LPVOID)obj, 0,&dwThreadId)) == NULL) 
    {
        return FALSE;
    }

    return TRUE;
}

extern "C" bool _declspec(dllexport) isThreadDone() 
{ 
    DWORD res = WaitForSingleObject(hThread, 10);
    if (res == WAIT_OBJECT_0)
        return TRUE;

    // Set error flag depending on other values of res
    dwThreadResult = res;
    return FALSE;
}

extern "C" DWORD _declspec(dllexport) isThreadErrored()
{
    return dwThreadResult;
}

Не имеет значения, есть лиwhile цикл в вашей inetTransfer функции или нет - вам, скорее всего, даже понадобится какой-то цикл!Функция downloadfile создает поток и возвращает.Другие функции используются для проверки успешного завершения потока.

...