我正在使用NSIS构建一个简单的安装程序,并希望在批处理脚本中以静默模式运行它,最后我会检查ERRORLEVEL:
REM a simple test
REM get into folder and run the installer
cd /d my_installer_path
my_installer_made_with_nsis.exe /S
if %ERRORLEVEL% NEQ 0 echo something has gone wrong
现在,似乎my_installer_made_with_nsis.exe始终返回%ERRORLEVEL% 0
,即使在nsi代码中我明确设置了错误级别并退出中止。
在我的nsi脚本中,我使用像
这样的ErrorHandling函数Function ErrorHandler
IfSilent +2 0
MessageBox MB_ICONSTOP "$err_msg"
DetailPrint "$err_msg"
SetErrorlevel 5 ; <---- APPARENTLY DOES NOT WORK
Abort
FunctionEnd
然后,在我的代码中,我像这样调用错误处理程序:
...
StrCpy $err_msg "An exception occurred: blah blah"
Call ErrorHandler
我希望cmd shell中的外部%ERRORLEVEL%为5,但它始终为0.
也许我在NSIS中错误地理解了ErrorLevel的整个概念,但在这种情况下有没有办法从命令shell中检索我的安装程序的退出代码?
答案 0 :(得分:1)
SetErrorlevel
正常工作,意思是,它设置了流程的退出代码。 %ERRORLEVEL%
不一定是子进程的退出代码,尤其是在调用GUI进程时。你的问题是你的批处理文件/ cmd.exe,而不是NSIS。
Function MyAbortFunction
SetErrorlevel 5
Abort
FunctionEnd
Section
System::Call 'Kernel32::GetEnvironmentVariable(t "TestAbort", p 0, i0)i.r0'
${If} $0 = 0
System::Call 'Kernel32::SetEnvironmentVariable(t "TestAbort", t "1")'
ExecWait '"$ExePath"' $0 ; Run the test instance of our self
MessageBox MB_OK "Exit code = $0" ; This will be 5
SetErrorlevel $0 ; Make the parent use the same code in case you are testing in cmd.exe
${Else}
Call MyAbortFunction
${EndIf}
SectionEnd
在cmd.exe中,这可以正常工作:
start "" /WAIT "c:\my\path\to\Test.exe"
echo %errorlevel%
答案 1 :(得分:0)
nsi脚本没什么问题
解决方案是:
在批处理脚本中使用 start /wait
这很简单,但对于NSIS的初学者来说并不那么明显。
如果您必须等待安装程序继续执行批处理脚本,则必须使用start /wait
,但首先您可能会错过,并且在谈到ERRORLEVEL时也会错过效果。
NSIS手册有许多运行静默卸载程序的好例子http://nsis.sourceforge.net/Docs/Chapter4.html#silent
但它没有提到start /wait
如果您参考手册示例:
foo.exe /S /D=C:\Program Files\Foo
(并假设foo非常简单, FAST 用于测试sakes)
当您在cmd shell中运行该命令时,您最初无法意识到shell没有等待。然后,如果你检查ERRORLEVEL,你可能会感到惊讶(像我一样)
如果要在交互模式下运行foo.exe时要测试ERRORLEVEL,可能会发生同样的情况。你无法意识到foo与shell“分离”。在这种情况下检查shell%ERRORLEVEL%是没有用的。
然后最后你发现有人建议必须使用启动/等待非控制台应用
http://forums.winamp.com/showpost.php?p=2530597&postcount=2
所以你应该使用这个命令行:
start /wait foo.exe /S /D=C:\Program Files\Foo`