2010-08-04 5 views
6

अद्यतन: यह D2007 के लिए विशिष्ट हो रहा है। यह डी 2010 में काम करता है जैसे यह पुराने संस्करण में काम करता है।डी 2007 के साथ अपवाद ब्लॉक से हल्ट (एन) के साथ एक त्रुटि कोड कैसे वापस करें?

मैं अपवाद के प्रकार की तरह Eception हैंडलर ब्लॉक में पकड़ा के आधार पर एक निकास कोड नहीं लौटाना चाहते हैं:

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 में, हॉल्ट (एन) एक अपवाद ब्लॉक से फोन कर रहा हमेशा रिटर्न एक एक्जिट कोड 1, इससे कोई फर्क नहीं पड़ता कि आप हल्ट() से क्या गुजरते हैं।

जाहिर है क्योंकि अपवाद संचालक से बाहर निकलने अंतिम रूप है, जो लंबित (गैर बीच में बंद करें) अपवाद को साफ करता है कहता है, SysUtils.ExceptHandler बुला:

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

और कोई बात नहीं क्या बाहर निकलने के कोड मैं चाहता था मुझे लगता है कि Halt(1) प्राप्त करें!

तो सवाल यह है:
कैसे मैं बस निर्भर करता है जो अपवाद पर उठाया गया था वांछित बाहर निकलें कोड लौट सकते हैं?

+0

माइक है, जो सच है के द्वारा नीचे टिप्पणी के आधार पर, यह वास्तव में सही ERRORCODE वापसी करता है। मुझे संदेह है कि यह वह तरीका है जिसका उपयोग आप त्रुटि कोड प्राप्त करने के लिए करते हैं जो संभवतः काम नहीं कर सकता है। – zz1433

+0

@Aldo। नहीं, यह डी 2007 है। वही सटीक चीज डी 2007 और डी 2010 के साथ अलग-अलग व्यवहार करती है, जहां माइक द्वारा अपेक्षित और रिपोर्ट की गई है। –

+0

कृपया क्यूसी (http://qc.embarcadero.com/) में एक बड़ी रिपोर्ट दर्ज करें; यद्यपि शायद डी2007 अपग्रेड नहीं होगा, यह देखने में सक्षम होना अच्छा है कि कौन सी बग 'ज्ञात' हैं। –

उत्तर

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; 

वैसे भी: it's a bug in D2007, which was fixed in D2010

+0

धन्यवाद! 'AcquireExceptionObject' के लिए +1 D2007 में एक वर्कअराउंड के रूप में मेरे लिए चाल कर रहा है। यह वास्तव में एक अच्छा बग था ... –

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. 

डेल्फी 5 में में संकलित लगता है, तो नीचे एक डॉस बॉक्स में भाग गया XP ...

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

C:\>echo %errorlevel% 
111 

C:\> 

ध्यान दें कि डॉस त्रुटि स्तर 0 65535 गूंज% errorlevel% करने की सीमा तक ही सीमित हैं त्रुटि स्तर को देखने के लिए सबसे तेज़ तरीका है।

भूल जाते हैं कि errorlevel पढ़ने यह साफ करता है मत करो।

+1

अब डी 2007 में काम नहीं करता है! लेकिन काम करने के लिए इस्तेमाल की पुष्टि के लिए धन्यवाद! मुझे बहुत यकीन था कि मैंने इसे पहले किया था .. ;-) –

+1

और यह डी 2010 में भी काम करता है। वही सटीक कोड, त्रुटि त्रुटि का परीक्षण करने का एक ही सटीक तरीका मुझे डी 2010 में डी 5 के साथ जैसा चाहता है, लेकिन डी 2007 के साथ, मुझे हमेशा 1 मिलता है! ExitProcess के लिए –

2

आप तुरंत किसी भी सफाई के बिना कार्यक्रम निरस्त करने के लिए, और वापसी एक निकास कोड चाहते हैं, ExitProcess प्रयास करें। हालांकि, ExitProcess का उपयोग करने पर कुछ चेतावनियों के लिए आलेख देखें।

+0

+1। यह मेरे वर्तमान मामले के लिए थोड़ा कठोर है, लेकिन याद रखने योग्य है। –

-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 के डिफ़ॉल्ट मान पर है, तो फ़ंक्शन 1 से बाहर निकलने के मूल डेल्फी व्यवहार में वापस आ जाता है, लेकिन अगर निकास कोड पहले से ही किसी अन्य चीज़ पर सेट हो चुका है, तो यह इसके बजाय उस मान के साथ रुक जाएगा। पहली बात यह है Halt वैश्विक ExitCode चर, करता सेट तो अपने कोड आगे कोई बदलाव की जरूरत है (हालांकि मैं Exitcode चर के लिए कोई अन्य नाम चुनें चाहते हैं) चाहिए। Halt पर आपका कॉल वैश्विक ExitCode चर सेट करेगा और फिर प्रोग्राम को बंद करने के लिए आगे बढ़ेगा। अपवाद संचालक कि ExitCode पहले से ही सेट किया गया है नोटिस करेंगे और फिर से फोन है कि बजाय मान 1 के साथ Halt

+5

दुर्भाग्य से, यह काम नहीं करता है। सबसे पहले, यह एक प्रक्रिया होनी चाहिए, एक समारोह नहीं, लेकिन 'DoneExceptions' में पहुंचने पर अधिक महत्वपूर्ण, कोड 'ExceptProc: = nil' रीसेट करता है, फिर सीधे' if (ExceptObject <> nil) को कॉल करता है और नहीं (ExceptObject EAbort है) छोड़कर हैंडलर (एक्सेप्ट ऑब्जेक्ट, एक्सेप्ट एडडर); ' –

0

का उपयोग रोकने के (आई) मेमोरी लीक उत्पन्न करता है (जैसा कि आप देख सकते हैं कि आप ReportMemoryLeaksOnShutdown साथ FastMM MemoryLeaks सक्षम करता है, तो: = true)

यह एक "स्वच्छ" बाहर निकलें उपयोग करने के लिए काफी बेहतर है और बाहर निकलने से पहले ExitCode सेट ।

उदाहरण के लिए एक सांत्वना अनुप्रयोग का एक मुख्य अनुभाग में:

ExitCode:=I; 
exit; 
संबंधित मुद्दे