0

我正在编写我的第一个 NSIS 脚本,但我在路上发现了一个颠簸。事实上,我认为仅在标题中很难解释,(也许有人可以帮助)所以让我充分解释一下:

我正在创建一个使用一些自定义页面的安装程序,因为我希望用户首先选择一些选项(它使用 nsDialogs),并根据它在安装路径中进行一些调整(主要是自动检测它,因为它可能取决于其他事情)。所有这些工作正常。

在该选项的某些情况下,在检查某些文件是否存在之间,它会对文件进行哈希处理以查看该文件是否是它所期望的文件(因为稍后它将用增量修补它)。我使用了Crypto 插件MD5 插件,两者都很好,都可以做我想做的事,但是它们会挂起安装程序一段时间(大约一秒钟),我想是因为文件有点大(大约超过 100MB)和附近就是问题所在。

通常在这些情况下,您选择该选项,进入下一个(自定义)页面,并在自定义页面的创建者功能中自动检测文件夹,并直接进行文件检查,当检查文件哈希时,它会挂起一秒钟并继续,但一直挂起它只显示一个空白页面,因为它还没有在创建函数中到达nsDialogs::Show指令来显示窗口内容。在该页面中,您可以更改文件夹,如果是这种情况,一旦更改,它会再次运行检查(这是在两种情况下都调用的专用函数)并再次挂起一段时间,但随后窗口显示所有内容并且我可以设置一个文本来表达一些东西(事实上,这是我第一次做的),但是第一次自动我不能这样做。

这就是重点:如何向用户显示一些内容以使他们了解安装程序正在执行哈希计算,而不是仅显示一个空白窗口。

我尝试过或想过要做的事情:

  • 使用 nsDialogs,因为它首先进行计算并且直到后来才到达nsDialogs::Show,所以我当时无法在窗口中显示任何内容(或者,至少是我在我找到的所有文档中阅读的内容关于那个)。而且,就像文档说的那样,它已经过测试,当你按下下一个或后退按钮时,你在nsDialogs::Show指令之后放置的所有内容都会被执行。
  • 看到 nsDialogs 起初似乎不是要走的路,我正在搜索是否可以在安装窗口上方显示一个窗口(类似于 MessageBox)并分别在哈希计算之前和之后自动关闭它,只显示一个文本用“请稍候”之类的。但我没有找到办法。
  • 也许使用计时器并在几毫秒后进行检查可以完成,但在我看来这是一种非常便宜的方法来处理一些等待发生的问题,主要是因为取决于机器速度,我只能在如果它首先使用nsDialogs::Show 显示窗口,然后使用计时器执行检查文件,这是最后的手段。但是,我想在设置文件夹时进行检查,因为该功能启用“下一步”按钮,我希望尽快这样做,并且向其中添加计时器看起来不正确。
  • 或者是其他更时尚的方式来做到这一点,但我还没有弄清楚。

如果对这个主题不太了解,我可以在明天添加一个从头开始创建的小例子来展示这一点,因为我的主要测试太大了,不应该在这里粘贴所有内容。

谢谢!

编辑:

这是问题的原始示例(不要忘记添加标记为大文件的路径):

Name "Example HASH Freeze"
Outfile "ExampleHASHFreeze.exe"

RequestExecutionLevel user
Unicode True
XPStyle on

!include nsDialogs.nsh
!include LogicLib.nsh

Page Custom FirstCreate
Page Custom SecondCreate
Page instfiles

var file
var hash
var info

Function FirstCreate

    StrCpy $file "" ; Add a path to a big file to do the hash. 150 MB or more.
    
    nsDialogs::Create 1018
    ${NSD_CreateLabel} 0u 64u 100% 12u "Hashing: $file"
    nsDialogs::Show
FunctionEnd

Function SecondCreate
    
    StrCpy $hash "hashing..."

    nsDialogs::Create 1018
    ${NSD_CreateLabel} 0u 58u 100% 12u "Hashing: $file"
    ${NSD_CreateLabel} 0u 70u 100% 12u "Hash: $hash"
    Pop $info

    call hashFile
    
    nsDialogs::Show
FunctionEnd

Function hashFile
    ${If} ${FileExists} "$file"
        md5dll::GetMD5File "$file"  ; Using MD5 Plugin
        ; Crypto::HashFile "MD5" "$file" ; Using Crypto Plugin
        Pop $0
        ${NSD_SetText} $info "Hash: $0" 
    ${Else}
        ${NSD_SetText} $info "Hash: FILE NOT FOUND" 
    ${EndIf}
FunctionEnd

Section
    MessageBox MB_OK "Hello world!"
SectionEnd

然而,使用Anders使用 Banner 插件的提示(这就是我正在搜索的内容!),以及带有 nsDialogs Timer 的BgWorker 插件,nsDialogs 渲染窗口,同时它执行显示横幅的哈希,所以现在看起来很完美!(不要忘记添加标记的大文件的路径)。

Name "Example HASH Freeze Fix"
Outfile "ExampleHASHFreezeFix.exe"

RequestExecutionLevel user
Unicode True
XPStyle on

!include nsDialogs.nsh
!include LogicLib.nsh

Page Custom FirstCreate
Page Custom SecondCreate
Page instfiles

var file
var hash
var info

Function FirstCreate

    StrCpy $file "" ; Add a path to a big file to do the hash. 150 MB or more.
    
    nsDialogs::Create 1018
    ${NSD_CreateLabel} 0u 64u 100% 12u "Hashing: $file"
    nsDialogs::Show
FunctionEnd

Function SecondCreate
    
    StrCpy $hash "hashing..."

    nsDialogs::Create 1018
    ${NSD_CreateLabel} 0u 58u 100% 12u "Hashing: $file"
    ${NSD_CreateLabel} 0u 70u 100% 12u "Hash: $hash"
    Pop $info
    
    GetFunctionAddress $0 onShow_hack
    nsDialogs::CreateTimer $0 1
    
    nsDialogs::Show
FunctionEnd

Function hashFile
    ${If} ${FileExists} "$file"
        Banner::show "Calculating Hash..."
        md5dll::GetMD5File "$file"  ; Using MD5 Plugin
        ; Crypto::HashFile "MD5" "$file" ; Using Crypto Plugin
        Pop $0
        Banner::destroy
        ${NSD_SetText} $info "Hash: $0" 
    ${Else}
        ${NSD_SetText} $info "Hash: FILE NOT FOUND" 
    ${EndIf}
FunctionEnd

Function onShow_hack
    GetFunctionAddress $0 ${__FUNCTION__}
    nsDialogs::KillTimer $0
    GetFunctionAddress $0 hashFile
    BgWorker::CallAndWait
FunctionEnd

Section
    MessageBox MB_OK "Hello world!"
SectionEnd

也许它应该在进行计算的同时禁用按钮,但这些事情很容易。谢谢!

4

1 回答 1

1

您真的不应该在自定义页面上做繁重的工作。您可以使用BgWorker 插件来做后台工作。将其与计时器技巧相结合,您将得到:

!include nsDialogs.nsh

Page Custom mypage

Function hashfile
Crypto::HashFile "MD5" "$somefilepath"
Pop $0
MessageBox "" $0
FunctionEnd

Function onShow_hack
GetFunctionAddress $0 ${__FUNCTION__}
nsDialogs::KillTimer $0
GetFunctionAddress $0 hashfile
BgWorker::CallAndWait
FunctionEnd

Function mypage
nsDialogs::Create 1018
Pop $0
${NSD_CreateButton} 0 13u 100% 12u "I do nothing"
Pop $0
GetFunctionAddress $0 onShow_hack
nsDialogs::CreateTimer $0 1
nsDialogs::Show
FunctionEnd

Section
SectionEnd

横幅插件允许您显示覆盖的消息...

于 2021-12-15T02:51:02.710 回答