【问题标题】:Inno script download file from internet Async从互联网异步下载 Inno 脚本文件
【发布时间】:2011-10-14 07:52:33
【问题描述】:

如何在 Inno 中从 Internet 下载文件。但请记住,我想要异步下载。换句话说,我希望下载从后台开始,并且 UI 会响应。

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

您能帮我解决这个问题吗?或者让我知道任何其他方式来实现这一目标?

【问题讨论】:

    标签: dll inno-setup pascal


    【解决方案1】:

    看看InnoTools Downloader。它正是为此目的而编写的,并提供了下载进度等。

    【讨论】:

    • 这个下载器阻塞了通话,我需要非阻塞功能才能上网。
    • 为什么?安装程序除了保持 UI 响应式之外,无能为力。
    【解决方案2】:

    我不确定这是否可以做到。您也许可以编写一个具有两个功能的扩展 DLL:

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

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

    另外,考虑一下,取消下载线程的另一个函数会很有用,因此您可以对取消的设置做出反应。

    请参阅this question 以查找有关如何从 Pascal 脚本调用 DLL 中的函数的提示。

    编辑
    为了更清楚地说明我希望这些函数做什么,我正在尝试编写一些伪代码(可能看起来有点像 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,直到它返回true。

    当然,这必须加上锁定机制,这里没有真正的错误报告,但我希望你能明白我的想法。

    编辑 2
    我会将您在 cmets 中发布的一些伪代码翻译成 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 函数中是否存在 while 循环并不重要 - 您很可能甚至需要某种循环! downloadfile 函数创建线程并返回。其他函数用于检查线程是否成功结束。

    【讨论】:

    • 感谢您分享宝贵的信息,能否请您布置一个算法或代码sn-p来支持上述方式。我知道如何编写扩展 dll,事实上我已经创建了 dll 并在之前的 inno 设置中使用过它。所以我知道该怎么做。你能分享或用C ++编写代码sn-p,它更清楚地描述了上述场景。对此的任何帮助将不胜感激。
    • 嗨,我不是一个 C++ 的人,所以我希望一些伪代码是可以的。我将编辑我的答案。
    • 或者你可能会去找迪安娜的答案...... ;-)
    • 不,调用将不会阻塞 - 线程 将一直运行直到下载完成。但是,当您将从 InnoSetup 调用的函数中启动一个新的并行处理(=> 线程)时,该函数将在启动线程后立即返回 - 这就是多线程的全部意义 :-)
    • 你错了。 your 实现阻塞的原因是对WaitForSingleObject 的调用。删除它,您的实现也不会阻塞。我的实现将不阻塞,因为我不等待线程在InnoSetup 调用的函数中完成。 while 循环阻塞线程(这是需要的),但线程独立运行。再说一遍:StartDownload 函数启动线程并返回。 thread 方法在 while 循环中运行,直到所有内容都下载完毕,但在后台运行,不会阻塞 InnoSetup。
    【解决方案3】:

    InnoTools 下载器好像很久没更新了,不支持 UNICODE...

    还有一个看起来很有希望的项目:https://bitbucket.org/mitrich_k/inno-download-plugin 它于 2016 年 12 月更新,支持 ANSI 和 UNICODE 版本的 InnoSetup。 它有示例,文档还可以,它甚至支持多种语言,如西班牙语、中文...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      • 2011-11-28
      • 2013-11-30
      • 2023-03-22
      相关资源
      最近更新 更多