gpt4 book ai didi

installation - NSIS ExecDos 插件 - IsDone 功能适用于某些计算机,但不适用于其他计算机

转载 作者:行者123 更新时间:2023-12-04 06:02:42 28 4
gpt4 key购买 nike

我有一个 NSIS 安装程序,它使用 ExecDOS调用运行 SQL 脚本的命令行工具的插件。在异步模式下调用 ExecDos,然后我循环更新进度条并调用 IsDone 函数,直到命令行工具完成。

我遇到的问题是,在某些计算机上,IsDone 检查错误地将进程报告为已完成,而实际上它仍在运行,因此在安装程序完成后它会在后台继续运行。我找不到它不能工作的计算机之间的任何共性,所以我希望有人有一些想法或可以发现我的代码中的错误。

Function UpdateDatabase
!insertmacro SetBannerText "Updating database" 0 0
!insertmacro Log "About to update the database"

StrCpy $UpdateDatabase_PreviousScriptNumber 0

SetShellVarContext all

Push "ExecDos::End" # Add a marker for the loop to test for.
ExecDos::exec /NOUNLOAD /ASYNC '"$ComSpec" /S /C ""$INSTDIR\Database\Tool\DatabaseResetTool.Console.exe" -sp="$INSTDIR\Database\Scripts" -cs="Data Source=$DatabaseServer;Initial Catalog=$Database;User ID=sa;Password=*********;Persist Security Info=true;MultipleActiveResultSets=True;Language=English" -eoe"' '' '$APPDATA\Company\$ApplicationPrefix\Database Update.log'
Pop $DatabaseUpdate_ProcessHandle
Loop:
ExecDos::isdone /NOUNLOAD $DatabaseUpdate_ProcessHandle
Pop $DatabaseUpdate_Done

StrCpy $0 "$APPDATA\Company\$ApplicationPrefix\Database Update.log"
StrCpy $1 "$TEMP\Database Update.log"
StrCpy $2 0
System::Call 'kernel32::CopyFile(t r0, t r1, b r2) ?e'

${LineRead} "$TEMP\Database Update.log" "-2" $DatabaseUpdate_LogFileLine

${StrTok} $DatabaseUpdate_LogFileLineEndPart $DatabaseUpdate_LogFileLine "(" "L" "1"
${StrTok} $DatabaseUpdate_ScriptNumber $DatabaseUpdate_LogFileLineEndPart "/" "0" "1"
${StrTok} $DatabaseUpdate_ScriptCountUnprocessed $DatabaseUpdate_LogFileLineEndPart "/" "1" "1"
${StrTok} $DatabaseUpdate_ScriptCount $DatabaseUpdate_ScriptCountUnprocessed ")" "0" "1"

${If} $DatabaseUpdate_ScriptNumber != ""
${AndIf} $DatabaseUpdate_ScriptCount != ""
FloatOp::D $DatabaseUpdate_ScriptNumber $DatabaseUpdate_ScriptCount
FloatOp::M $0 100

${If} $UpdateDatabase_PreviousScriptNumber != $DatabaseUpdate_ScriptNumber
!insertmacro SetBannerText "Updating database$\r$\n$\r$\nRunning script $DatabaseUpdate_ScriptNumber of $DatabaseUpdate_ScriptCount" 0 $0
StrCpy $UpdateDatabase_PreviousScriptNumber $DatabaseUpdate_ScriptNumber
${EndIf}
${EndIf}

Sleep 200

StrCmp $DatabaseUpdate_Done "0" Loop Done
Done:
Push "$TEMP\Database Update.log"
Push "exception"
Call FileSearch
Pop $0
Pop $1

${If} $0 != "0"
StrCpy $InstallError 1
!insertmacro LogError "Database update failed. Please review the 'Database Update.log' to see the detail error message" ""
${EndIf}
FunctionEnd

最佳答案

我不知道确切的问题是什么,但您的脚本还有一些其他问题,您可能应该修复:

  • System::Call 'kernel32::CopyFile(t r0, t r1, b r2) ?e' b不是有效的系统插件类型,请使用 i . ?e压入堆栈,您永远不会弹出此值,也不会检查复制是否成功。将其替换为 System::Call 'kernel32::CopyFile(t r0, t r1, i 0)i.r0'并联系 ${If} $0 = 0 ...deal with error
  • 您正在使用 $ComSpec 和 ""我认为这是为了处理 cmd.exe 引用问题,ExecDos 使用管道,因此重定向应该可以在不将 cmd.exe 混入的情况下工作。尝试只执行 ExecDos::exec /NOUNLOAD /ASYNC '"$INSTDIR\Da...
  • 你并没有真正控制 $Temp 中的所有文件,使用 $Pluginsdir 作为你的暂存空间
  • 您永远不会弹出并测试 Push "ExecDos::End"

  • 您可能想要调查的其他一些事情:
  • SetShellVarContext all将 $APPDATA 转换为常见的 appdata/programdata,因此请确保您是管理员。
  • 尝试更长的 sleep 时间...
  • ?e有没有可能您从未弹出的值最终会填充堆栈,因此永远不会将 isdone 参数插入堆栈,因此函数最终会使用无效参数?

  • 要调试它,您应该能够用 System::Call 'kernel32::WaitForSingleObject(i $DatabaseUpdate_ProcessHandle
    ,i 0)i.r0'
    替换对 isdone 的调用。并将 $0 中的值与 return values listed on MSDN 进行比较.

    关于installation - NSIS ExecDos 插件 - IsDone 功能适用于某些计算机,但不适用于其他计算机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8769564/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com