2010-08-04 13 views
6

Güncelleştirme: D2007'ye özgü gibi görünüyor. D2010'da eski sürümde çalıştığı gibi çalışır.D2007 ile bir Özel durum satırından Halt (n) ile bir hata kodu nasıl verilir?

ben gibi eception Handler bloğunda yakalanan İstisna türüne bağlı olarak bir çıkış kodu dönmek istiyorum: Bir İstisna bloktan durdur (n) çağırarak maalesef D2007 içinde

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. 

, hep döner Halt() öğesine ne geçerseniz gidin, bir Çıkış kodu 1. olursa olsun Halt(1) olsun ne istediğini çıkış kodu

procedure ExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer); far; 
begin 
    ShowException(ExceptObject, ExceptAddr); 
    Halt(1); // <= @#$##@#$! 
end; 

Ve:

İstisna işleyicisi çıkan SysUtils.ExceptHandler çağırarak, beklemede (non İptal) İstisnalar temizler Sonlandrmay, çağırır Görünüşe çünkü!

Yani soru şu:
basitçe nasıl büyüdü hangi İstisna bağlı istenilen çıkış kodu döndürebilir?

+0

, gerçekten doğru ERRORCODE çıkmıyor. Beklendiği gibi çalışmayabilir ErrorCode almak için kullandığınız yöntem olduğundan şüpheleniyorum. – zz1433

+0

@Aldo. Hayır, D2007. Aynısı, D2007 ve D2010 ile Mike tarafından beklendiği ve raporlandığı gibi farklı şekilde davranır. –

+0

Lütfen QC'de büyük bir rapor hazırlayın (http://qc.embarcadero.com/); Muhtemelen bir D2007 yükseltmesi olmayacak olsa da, hangi hataların 'bilinen' olduğunu görmek mümkün. –

cevap

5

Bu işe yarar mı?

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); 

Veya bu nedir? Her neyse: it's a bug in D2007, which was fixed in D2010. halt (I) kullanarak

+0

Teşekkürler! AcquireExceptionObject' için +1, D2007'de bir geçici çözüm olarak benim için hile yapıyor. Bu gerçekten güzel bir hataydı ... –

2

Aslında ... o zaman altında bir DOS kutusunda koştum, amaçlandığı gibi ben kodunuzu kullanılan

...

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 ile derlendi .... iş gibi görünüyor XP ... DOS hatası Seviyeleri 0 65535 Echoing% errorlevel% aralığında sınırlı olduğunu

C:\>test1 
Enter error code: 
111 
EExternal: sdsdkfjh 

C:\>echo %errorlevel% 
111 

C:\> 

Not hata seviyesini görmek için en hızlı yoludur.

Hata seviyesinin okunmasının bunu temizlediğini unutmayın. Hemen bir çıkış kodu herhangi temizleme olmadan programı iptal ve geri dönmek isterseniz

+1

Artık D2007'de çalışmıyor! Ama işe yaradığını doğruladığın için teşekkürler! Daha önce bu şekilde yapmış olduğumdan çok eminim. ;-) –

+1

Ayrıca D2010'da da çalışıyor. Aynı kesin kod, hata seviyesini test etmenin tam olarak aynı yolu D2010'da D510'da sizin için ne istediğimi verir, ancak D2007 ile her zaman 1 alırım! ExitProcess için –

2

, ExitProcess deneyin. Yine de, ExitProcess'i kullanırken birkaç uyarı için makaleye bakın.

+0

+1. Mevcut davam için biraz fazla sert ama hatırlamaya değer. –

-1

yerleşik özel durum işleme fonksiyonu ne gibi yapmazsa, o zaman kendi ile değiştirin: Küresel System.ExceptProc değişkene program başlar

function ExitCodeExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer); 
begin 
    ShowException(ExceptObject, ExceptAddr); 
    if ExitCode = 0 then 
    ExitCode := 1; 
    Halt(ExitCode); 
end; 

Atama zaman o:

ExceptProc := @ExitCodeExceptHandler; 

küresel ExitCode değişkeni kullanacak şekilde uyguladık. Eğer hala 0 varsayılan değerinde ise, fonksiyon 1 ile çıkmanın orijinal Delphi davranışına geri döner, fakat eğer çıkış kodu zaten başka bir şeye ayarlanmışsa, o zaman bunun yerine bu değerle durur. (Ben Exitcode değişken için farklı bir ad seçin ediyorum rağmen) kodunuzu başka bir değişiklik gerektiğinde bu yüzden ilk şey Halt, küresel ExitCode değişkeni ayarlanır gelmez. Halt numaralı çağrıya, global ExitCode değişkenini ayarlayacak ve ardından programı kapatmaya devam edeceksiniz. İstisna işleyici, ExitCode'un zaten ayarlanmış olduğunu ve Halt'u 1 yerine bu değerle yeniden çağırdığını fark edecektir.

+5

Maalesef işe yaramıyor. İlk önce, bir işlev değil, bir işlev olmalıdır, ancak daha fazla DoneExceptions 'geldiğinde önemli, kod sıfırlar' ExceptProc: = nil 'sonra doğrudan çağırır (ExceptObject <> nil) ve değil (ExceptObject ise EAbort) o zaman ExceptHandler (ExceptObject, ExceptAddr); –

0

bellek sızıntılarını üretir (Gördüğünüz o size ReportMemoryLeaksOnShutdown ile FastMM MemoryLeaks etkinse: = true;)

Bu bir "Temiz" Çık kullanmak çok daha iyi ve önceki çıkmadan exitCode set . Örneğin bir konsol uygulamasının ana bölümünde

: doğrudur Mike, aşağıda yorum dayanarak

ExitCode:=I; 
exit; 
İlgili konular