Dll Inno脚本从internet异步下载文件

Dll Inno脚本从internet异步下载文件,dll,inno-setup,pascal,Dll,Inno Setup,Pascal,如何在Inno中从internet下载文件。但是请记住,我想要异步下载。换言之,我希望下载从后台开始,UI能够响应 据我所知,似乎没有任何方法可以在inno脚本中下载异步,因为它不支持thead和timer 你能帮我做这件事吗?或者让我知道实现这一点的其他方法吗?我不确定是否能做到。您可能可以使用两个函数编写扩展DLL: 一个是为下载生成新线程(传递下载URL和临时文件名),另一个是可以定期调用以检查下载是否完成或是否发生错误的线程 然后在安装程序启动时调用第一个函数(确保卸载时不启动下载)。当

如何在Inno中从internet下载文件。但是请记住,我想要异步下载。换言之,我希望下载从后台开始,UI能够响应

据我所知,似乎没有任何方法可以在inno脚本中下载异步,因为它不支持thead和timer


你能帮我做这件事吗?或者让我知道实现这一点的其他方法吗?

我不确定是否能做到。您可能可以使用两个函数编写扩展DLL:

一个是为下载生成新线程(传递下载URL和临时文件名),另一个是可以定期调用以检查下载是否完成或是否发生错误的线程

然后在安装程序启动时调用第一个函数(确保卸载时不启动下载)。当需要下载的文件时,调用第二个方法。在某个时候,您需要等待下载完成

另外,考虑一下,另一个取消下载线程的函数将非常有用,这样您就可以对取消的设置做出反应

有关如何从Pascal脚本调用DLL中函数的提示,请参阅

编辑
为了更清楚地了解这些函数的作用,我正在尝试编写一些伪代码(可能看起来有点像C-):

在Inno设置中,首先调用
StartDownload
方法。如果在调用了
StartDownload
后取消了安装(只有这时才有线程!),请调用
CancelThread

在需要确保文件已下载时,反复调用
IsThreadDone
,直到返回true

当然,这需要加上锁定机制,这里没有真正的错误报告,但我希望您了解我的想法

编辑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;
}

inetransfer
函数中是否存在
while
循环并不重要-您甚至可能需要某种循环!
downloadfile
函数创建线程并返回。其他函数用于检查线程是否已成功结束。

查看。它正是为了这个目的而编写的,并给出了下载进度等。

看起来InnoTools Downloader很长时间没有更新,不支持UNICODE

还有一个项目看起来很有希望: 它于2016年12月更新,支持InnoSetup的ANSI和UNICODE版本。
它有示例,文档还可以,它甚至支持多种语言,如西班牙语、汉语……

感谢您分享宝贵的信息,您可以让layout使用算法或代码片段来支持上述方式吗。我知道如何编写扩展dll,事实上我已经创建了dll并在inno安装程序中使用了它。所以我知道怎么做。您可以共享或写入C++中的代码片段,它更清楚地描述了上面的场景。我会非常感激的。嗨,我不是C++的家伙,所以我希望一些伪代码可以。我将编辑我的答案。或者你可以选择迪安娜的答案…;-)不,调用不会阻塞-线程将运行,直到下载完成。但是,当在您将从InnoSetup调用的函数中启动新的并行处理(=>线程)时,该函数将在启动线程后立即返回-这就是多线程的全部含义:-)您错了。实现阻塞的原因是调用
WaitForSingleObject
。删除此选项,您的实现也不会阻塞。我的实现不会阻塞,因为我不会等待线程在从InnoSetup调用的函数中完成。
while
循环阻塞线程(这是需要的),但线程是独立运行的。同样地:
StartDownload
函数启动线程并返回。thread方法在while循环中运行,直到所有内容都被下载,但在后台不会阻止InnoSetup。此下载程序阻止调用,我需要非阻止功能进行internet下载。原因是什么?安装程序除了保持UI的响应性外,无法做很多其他事情。
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;
}