Я не уверен, что это можно сделать.Возможно, вы сможете написать 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
создает поток и возвращает.Другие функции используются для проверки успешного завершения потока.