更新:它似乎特定于D2007。它在D2010中工作,就像它在旧版本中工作一样。
我想返回一个退出代码,具体取决于Eception Handler块中捕获的异常类型,如:
program test;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
Exitcode: Integer;
begin
Writeln('Enter error code:');
Readln(Exitcode);
try
raise EExternal.Create('sdsdkfjh');
except
on E:EExternal do
begin
Writeln(E.Classname, ': ', E.Message);
Halt(Exitcode);
end;
end;
end.
不幸的是,在D2007中, 从异常块调用Halt(n)始终返回退出代码1 ,无论您传递给Halt()。
显然,因为从Exception处理程序退出调用Finalize,它会清除挂起(非Abort)异常,调用SysUtils.ExceptHandler:
procedure ExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer); far;
begin
ShowException(ExceptObject, ExceptAddr);
Halt(1); // <= @#$##@#$!
end;
无论我想要什么退出代码,我都会得到Halt(1)
!
所以问题是:
如何根据引发的异常情况简单地返回所需的退出代码?
答案 0 :(得分:5)
这会有用吗?
NeedHalt := False;
try
raise EExternal.Create('sdsdkfjh');
except
on E:EExternal do
begin
Writeln(E.Classname, ': ', E.Message);
NeedHalt := True;
end;
end;
if NeedHalt then
Halt(Exitcode);
还是这个?
try
raise EExternal.Create('sdsdkfjh');
except
on E:EExternal do
begin
Writeln(E.Classname, ': ', E.Message);
AcquireExceptionObject;
Halt(Exitcode);
end;
end;
答案 1 :(得分:2)
实际上......似乎按预期工作......
我用过你的代码......
program test1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
Exitcode: Integer;
begin
Writeln('Enter error code:');
Readln(Exitcode);
try
raise EExternal.Create('sdsdkfjh');
except
on E:EExternal do
begin
Writeln(E.Classname, ': ', E.Message);
Halt(Exitcode);
end;
end;
end.
在Delphi 5中编译,然后在XP下的DOS框中运行...
C:\>test1
Enter error code:
111
EExternal: sdsdkfjh
C:\>echo %errorlevel%
111
C:\>
请注意,DOS错误级别限制在0到65535的范围内。回显%errorlevel%是查看错误级别的最快方法。
不要忘记阅读错误级别会清除它。
答案 2 :(得分:2)
如果您想立即中止程序而不进行任何清理,并返回退出代码,请尝试ExitProcess。但请参阅文章,了解有关使用ExitProcess的一些注意事项。
答案 3 :(得分:0)
使用halt(I)会产生内存泄漏(如果你使用ReportMemoryLeaksOnShutdown启用FastMM MemoryLeaks:= true,你可以看到);
使用&#34; Clean&#34;会好得多。退出并在退出前设置ExitCode。
例如,在控制台应用程序的主要部分中:
ExitCode:=I;
exit;
答案 4 :(得分:-1)
如果内置的异常处理函数没有按照您的意愿执行,请将其替换为您自己的:
function ExitCodeExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer);
begin
ShowException(ExceptObject, ExceptAddr);
if ExitCode = 0 then
ExitCode := 1;
Halt(ExitCode);
end;
在程序启动时将其分配给全局System.ExceptProc
变量:
ExceptProc := @ExitCodeExceptHandler;
我已将其实现为使用全局ExitCode
变量。如果它仍然是默认值0,那么该函数将恢复为原始Delphi行为,退出时为1,但如果退出代码已经设置为其他内容,那么这将停止使用该值。 Halt
做的第一件事是设置全局ExitCode
变量,因此您的代码不需要进一步更改(尽管我为Exitcode
变量选择了不同的名称)。您对Halt
的调用将设置全局ExitCode
变量,然后继续关闭该程序。异常处理程序会注意到ExitCode
已设置,并使用该值而不是1重新调用Halt
。