Check/Prevent Windows 关闭 (NSIS)

Check/Prevent Windows Shutdown (NSIS)

总而言之,如果 he/she 决定在安装程序 运行 时关闭计算机,我需要检查 and/or 阻止用户。现在我研究了一段时间并得出以下结论:

${If} ${AtMostWinXP}
    System::Call `kernel32::GetModuleHandle(i0)i.r3`
    System::Call `user32::CreateWindowEx(i0,t"STATIC",t"MyApp",i0,i0,i0,i0,i0,i$HWNDPARENT,i0,ir3,i0)i.r1`
${ElseIf} ${AtLeastVista}
    System::Call `user32::ShutdownBlockReasonCreate(ir1,w"MyApp is running and still needs to clean up before shutting down!")i.r0`
${EndIf}

但是上面的代码片段不起作用。我错过了什么吗?我试过只使用:

System::Call `kernel32::GetModuleHandle(i0)i.r3`
System::Call `user32::CreateWindowEx(i0,t"STATIC",t"MyApp",i0,i0,i0,i0,i0,i$HWNDPARENT,i0,ir3,i0)i.r1`
System::Call `user32::ShutdownBlockReasonCreate(ir1,w"MyApp is running and still needs to clean up before shutting down!")i.r0`

因为前两个调用适用于 Windows XP 及更早版本,第三个调用适用于 Windows Vista 或更高版本,但被 Windows XP 及更早版本忽略(我没有证据支持这个理论)。这也行不通。

此外,我可以使用 user32::ShutdownBlockReasonCreate(ir1,w"$(PreventShutdown)")i.r0 而不是在上面的代码片段中使用整个字符串来支持不同的语言,对吧?

您的 Windows XP 代码没有意义,window 需要处理 WM_QUERYENDSESSION 以阻止关机。幸运的是 NSIS 已经为您处理 WM_QUERYENDSESSION

在 Vista 及更高版本中使用类似这样的东西:

LoadLanguageFile "${NSISDIR}\Contrib\Language Files\English.nlf"
LangString BlockReason ${LANG_ENGLISH} "Installer blah blah"
LoadLanguageFile "${NSISDIR}\Contrib\Language Files\Swedish.nlf"
LangString BlockReason ${LANG_SWEDISH} "Installer bork bork"

!include nsDialogs.nsh ; For WS_CHILD
!define /ifndef WS_POPUP 0x80000000
!include LogicLib.nsh

Function CreateShutdownBlockReason
StrCpy  $hwndParent
${If}  Z= 0 ; $hwndParent is 0, create a new window for silent installers
    System::Call 'USER32::CreateWindowEx(i0, t "STATIC", t "$(^Name)", i ${WS_CHILD}|${WS_POPUP}, i0, i0, i0, i0, p r1, i0, i0, i0)p.r1'
${EndIf}
System::Call 'USER32::ShutdownBlockReasonCreate(p r1, w "$(BlockReason)")'
FunctionEnd

Function .onInit
IfSilent 0 +2
Call CreateShutdownBlockReason ; .onGuiInit is not executed in silent installers
FunctionEnd

Function .onGuiInit
Call CreateShutdownBlockReason
FunctionEnd

我不确定静默安装程序是否能够阻止关机,但这是您在没有插件的情况下所能做的最好的事情。