上一个讨论try..except的帖子分数给的太少了,真是不好意思。
重新开这个帖子继续讨论,希望大家多给点指点。
 heluqing(鉴之小河〖挣大钱娶美女〗试验了我的那几行程序,可以执行成功,
并且给我做了改进,程序如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
    try
        mkdir('x:\aaa')
    except
        //showmessage('wrong!');
        on E:Exception do
        begin
            showmessage(E.Message);
        end;
    end;
end;
------------改成这样你就会看到错误提示:Invalid filename我试验了一下,还是没有成功,没有看到任何提示信息,点了按钮之后没有任何动静。
我试着F7执行了程序,结果发现根本没有执行except这一段,感觉很奇怪。
大家帮忙分析一下,为什么没有转入到excpet中执行。
我肯定没有X盘,这个目录肯定是没有建立成功的。另外,我想问问,对于mkdir这条语句执行的结果能获取到吗?
比如在watch中可以获取到吗?
有什么方法跟踪到?

解决方案 »

  1.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        try
            mkdir('C:\aaa') //检查盘符是否错误
        except
            //showmessage('wrong!');
            on E:Exception do
            begin
                showmessage(E.Message);
            end;
        end;
    end;
    我执行就能成功
      

  2.   

    run -> evaluate/modify or ctrl + F7
    单步执行 可以查看结果
      

  3.   

    naner_china(naner)
    能说更清楚点吗?
    ctrl+F7出来的窗口中expression中应该填写什么?
      

  4.   

    我执行成功了啊,也可以跟踪到shwomessage那行代码!
      

  5.   

    完蛋!
    难道rpwt?
    盗版有问题?
    delphi6有补丁不?
      

  6.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        {$I+}             <---此处换成 {$I-} 再试验
        try
            mkdir('x:\aaa');
            //ShowMessage(IntToStr(IOResult));  //{$I-} 的时候去掉注释
        except
            on E:Exception do
            begin
                showmessage(E.Message);
            end;
        end;
    end;
      

  7.   

    我试验了一下,
    I+的时候没有任何反应,
    I- 并且去掉了注释的时候,
    showmessage给出的文字是: 3。
    这代表什么?之后程序没有按照预想的转入到except中去执行。
    晕倒啊~~~~!
    这是怎么回事啊?
    求救啊求救~~~!
      

  8.   

    非要使用MkDir么?
    CreateDir不可以么?http://lysoft.7u7.net
      

  9.   

    唉,
    明显有人没有看懂我的主要意思。
    现在的问题是mkDir在使用的时候没有办法转入到except之中去,
    而不是mkDir有问题。
    我主要想弄清楚的是try..except的用法。另外说一句,
    CreateDir我早试过了,
    同样没有转入到except中去。请大家继续发表意见。
    {I-}的时候,
    IOResult是3。
    这怎么回事?
      

  10.   

    回复人: CentaurCao(草原) ( ) 信誉:94  2005-05-16 23:25:00  得分: 0  
     
     
       完蛋!
    难道rpwt?/////难道你也是Moper呵呵????
    盗版有问题?
    delphi6有补丁不?///////我执行是可以的,难道是编译器优化掉了?应该不会吧。我回去查查资料;  
     
      

  11.   

    回复人: ly_liuyang(Liu Yang) ( ) 信誉:221  2005-05-18 13:53:00  得分: 0  
     
     
       非要使用MkDir么?
    CreateDir不可以么?http://lysoft.7u7.net
      
     
    这两个是一个东东的说procedure MkDir(const S: string);
    begin
      MkDir(PChar(s));
    end;procedure MkDir(P: PChar);
    begin
    {$IFDEF MSWINDOWS}
      if not CreateDirectory(P, 0) then
    {$ENDIF}
    {$IFDEF LINUX}
      if __mkdir(P, -1) <> 0 then
    {$ENDIF}
        InOutError;
    end;
    公司里装的是d6,不知道d7里什么样子看上面的代码就知道了这个不抛出异常,只是在CreateDirectory失败的时候什么都不作楼上用D7能抛出异常的兄弟把代码贴出来这样就知道6\7有啥差别了
      

  12.   

    不知道上CSDN的兄弟有多少还是上mop的,呵呵,上来留个名吧...
      

  13.   

    寒……看没看InOutError着一行晕死啦,哈哈
      

  14.   

    我这里也捕获不到这个异常但是单步调试
    能跟踪到io异常为183trying... ...
      

  15.   

    晕啥乱78噪的不搞了,吃饭去啦
    另外,楼主,系统错误在MSDN上可以查到你问的3是3 The system cannot find the path specified.  ERROR_PATH_NOT_FOUND 我说的183是183 Cannot create a file when that file already exists.  ERROR_ALREADY_EXISTS 
      

  16.   

    另外还有2个123 The file name, directory name, or volume label syntax is incorrect.ERROR_INVALID_NAME
    21 The device is not ready.  ERROR_NOT_READY 
    试了下,以下异常还算正确MkDir('D:\aaa') //183 ,已经有啦
    MkDir('E:\aaa') //21 ,E是光驱
    MkDir('X:\aaa') //3
    MkDir('123:\aaa') //123 
    但是为什么捕获不到?俺不知道啦
      

  17.   

    NND真粗心procedure MkDir(P: PChar);
    begin
    {$IFDEF MSWINDOWS}
      if not CreateDirectory(P, 0) then
    {$ENDIF}
    {$IFDEF LINUX}
      if __mkdir(P, -1) <> 0 then
    {$ENDIF}
        InOutError;
    end;procedure InOutError;
    begin
      SetInOutRes(GetLastError);
    end;procedure SetInOutRes(NewValue: Integer);
    begin
      InOutRes := NewValue;
    end;  InOutRes: Integer;
    NND,能抛出异常才怪呢谁把D7的代码贴出来看看,对比一下就知道了
      

  18.   

    D7的procedure TForm1.Button1Click(Sender: TObject);
    begin
      try
      MkDir('c:\windows');
      except
        ShowMessage('Error');
      end;
    end;完全OK!http://lysoft.7u7.net
      

  19.   

    看里面!把MkDir里面的实现贴出来瞧瞧
      

  20.   

    楼主不妨试试这个
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        raise Exception.Create('我就是传说中的异常了!');
    end;
      

  21.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        try
            raise Exception.Create('我就是传说中的异常了!');
        except on E:exception do
            ShowMessage('报告,抓住一个异常,它竟然是这么写的:'+#13#10+e.Message);
        end;
    end;
      

  22.   

    procedure MkDir(const S: string);
    begin
      MkDir(PChar(s));
    end;procedure MkDir(P: PChar);
    begin
    {$IFDEF MSWINDOWS}
      if not CreateDirectory(P, 0) then
    {$ENDIF}
    {$IFDEF LINUX}
      if __mkdir(P, -1) <> 0 then
    {$ENDIF}
        InOutError;
    end;上面是D7的...
      

  23.   

    谁把D7里MkDir的实现代码贴出来瞧瞧啊!!!!!
      

  24.   

    继续把InOutError里面也贴出来
      

  25.   


    这屋到底是说什么的?
    怎么感觉各说各的
    那俺也继续mop么,好久不上了,贴子太长,看一个就得一下午
    不过俺当年在mop发了一个贴子,给俺赚了第一笔mb,但是后来被转了无数次,再后来从google上发现,网上到处都是了,晕,一开始还抗议抗议,发现自己的呐喊声只有自己能听见后就再也不喊了
    不是嗓子哑了,而是……习

      

  26.   

    我晕啊!
    不过还是感谢大家在此讨论了一番。我就是奇怪我用D6,
    为什么执行这么一小段程序没有抛出异常。
    不知道哪里有问题。还有用D6的吗?
    难道都能正常showmessage?
      

  27.   

    NND,也没人配合一下家里D7,公司D6来回试真麻烦回来后用D7跟踪了一下执行到InOutError; //内部实现跟D6一样,会赋值InOutRes但是访问InOutError,会执行function _GetTls: Pointer;调用发生在这里procedure       __IOTest;
    asm
            PUSH    EAX
            PUSH    EDX
            PUSH    ECX
            CALL    SysInit.@GetTLS   〈----------就是这里
            CMP     [EAX].InOutRes,0  
            POP     ECX
            POP     EDX
            POP     EAX
            JNE     @error
            RET
    @error:
            XOR     EAX,EAX
            JMP     Error
    end;看__IOTest的声明{ Procedures and functions that need compiler magic }
     ……
    procedure __IOTest;
    所以D7里{$I+}就会抛出异常
    {$I-}就没有异常至于异常的抛出就不多说了,__IOTest被多次调用,最终一旦执行到JMP     Error就procedure Error(errorCode: TRuntimeError);
    asm
            AND     EAX,127
            MOV     EDX,[ESP]
            JMP     ErrorAt
    end;procedure ErrorAt(ErrorCode: Byte; ErrorAddr: Pointer);const
      reMap: array [TRunTimeError] of Byte = (
        0,   { reNone }
        203, { reOutOfMemory }
        204, { reInvalidPtr }
        200, { reDivByZero }
        201, { reRangeError }
    {   210    Abstract error }
        215, { reIntOverflow }
        207, { reInvalidOp }
        200, { reZeroDivide }
        205, { reOverflow }
        206, { reUnderflow }
        219, { reInvalidCast }
        216, { reAccessViolation }
        218, { rePrivInstruction }
        217, { reControlBreak }
        202, { reStackOverflow }
        220, { reVarTypeCast }
        221, { reVarInvalidOp }
        222, { reVarDispatch }
        223, { reVarArrayCreate }
        224, { reVarNotArray }
        225, { reVarArrayBounds }
    {   226    Thread init failure }
        227, { reAssertionFailed }
        0,   { reExternalException not used here; in SysUtils }
        228, { reIntfCastError }
        229  { reSafeCallError }
    {$IFDEF LINUX}
    {   230   Reserved by the compiler for unhandled exceptions }
    {   231   Too many nested exceptions }
    {   232   Fatal signal raised on a non-Delphi thread }
        , 233, { reQuit }
        234  { reCodesetConversion }
    {$ENDIF}
    );begin
      errorCode := errorCode and 127;
      if Assigned(ErrorProc) then
        ErrorProc(errorCode, ErrorAddr);//<- ErrorProc := ErrorHandler; 在SysUtils.InitExceptions中
      if errorCode = 0 then
        errorCode := InOutRes
      else if errorCode <= Byte(High(TRuntimeError)) then
        errorCode := reMap[TRunTimeError(errorCode)];
      RunErrorAt(errorCode, ErrorAddr);
    end;
    procedure ErrorHandler(ErrorCode: Byte; ErrorAddr: Pointer); export;
    var
      E: Exception;
    begin
      case ErrorCode of
        Ord(reOutOfMemory):
          E := OutOfMemory;
        Ord(reInvalidPtr):
          E := InvalidPointer;
        Ord(reDivByZero)..Ord(High(TRuntimeError)):
          begin
            with ExceptMap[ErrorCode] do
              E := EClass.Create(EIdent);
          end;
      else
        E := CreateInOutError; 
      end;
      raise E at ErrorAddr;〈--在这里抛出
    end;D6里是不是这样,我白天没仔细跟踪隐约记的处理的没这么仔细楼主要是等不及,晚上自己看看D6里是不是这样要不等我明天回公司再看一下:(
      

  28.   

    D6里的实现跟上面差不多,只是ErrorHandler里代码由少许差别但是应该不影响大局的说但是奇怪的很__IOTest不会被执行不管{$I+}还是{$I-}我想这就是问题所在了谁装的D6,在Sysytem.__IOTest里设一下断点然后改变运行一下,例如{$I+}
    MkDir('X:\121212');
    {$I-}
    MkDir('X:\aaaa12');看能不能进入IOTest
    D7里肯定可以应该算是D6的一个BUG吧打一下补丁再试试
      

  29.   

    我用的是D7,可以捕获到异常,mkdir 调用的是System单元的这个方法:
    procedure MkDir(P: PChar);
    begin
    {$IFDEF MSWINDOWS}
      if not CreateDirectory(P, 0) then
    {$ENDIF}
    {$IFDEF LINUX}
      if __mkdir(P, -1) <> 0 then
    {$ENDIF}
        InOutError;
    end;查一下D6的相关代码就知道了嘛。
      

  30.   

    天哪!
    这么复杂的东西啊……
    晕倒!
    我本身只是想讨论一下try..except的用法的……对了,
    是不是D6有补丁的?
      

  31.   

    try..except的用法本身没啥好说的只是你这个例子恰好出现了捕捉不到异常的情况俺开始没看清楚,说了错的答案,犯了想当然的错误怕误人子弟,所以就关注了一下另外上面那一大堆,也顺便回答了你的那个问题==============================
    {I-}的时候,
    IOResult是3。
    这怎么回事?
    ================================
      

  32.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        {$I+}             <---此处换成 {$I-} 再试验
        try
            mkdir('x:\aaa');
            //ShowMessage(IntToStr(IOResult));  //{$I-} 的时候去掉注释
        except
            on E:Exception do
            begin
                showmessage(E.Message);
            end;
        end;
    end;就是这段程序。
    {I-}的时候showmessage给出的结果是3
      

  33.   

    我下载了D6的补丁,打上之后,异常出现了。
    我用的还是最原始的代码:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        try
            mkdir('x:\aaa')
        except
            showmessage('wrong!');
        end;
    end;D6给出了错误:
    ...raised exception clase EInOutError with message 'Invalid filename'...
    这倒是意料之中的,
    但是问题是还是没有转入到except语句中去。
    应该怎么处理才能转入到excpet语句中呢?
      

  34.   

    try
            mkdir('X:\aaa') 
        except
            showmessage('自定义异常信息!');//这在D7下也不能执行到
        end;
      

  35.   

    异常出现了但没转到except里面?
    框档……
      

  36.   

    楼主试过我的这段代码了木有啊?
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        try
            raise Exception.Create('我就是传说中的异常了!');
        except on E:exception do
            ShowMessage('报告,抓住一个异常,它竟然是这么写的:'+#13#10+e.Message);
        end;
    end;
      

  37.   

    在D7中可以执行自定义异常信息(通过EXE测试一目了然)
        try
          mkdir('X:\aaa');
        except
          showmessage('自定义异常信息!');
        end;
      

  38.   

    报告 hellolongbin(一个人[.net学习中……]) 
    你的代码我试验过了!
    木有成功哇!
    程序被中断了,
    提示信息写在了delphi的提示信息中……
    我那个心儿巴凉巴凉滴……
      

  39.   

    不要在delphi中编译状态下执行哪个程序,肯定会停住的,然后F9才能继续下一步,你执行编译好的可执行文件,会不会出现提示框那?就是我原来给你的那段代码,用上看看...
      

  40.   

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        try
            mkdir('x:\aaa')
        except
            //showmessage('wrong!');
            on E:Exception do
            begin
                showmessage(E.Message);
            end;
        end;
    end;
      

  41.   

    to 楼主:主要是让你看能不能show出错误提示……
      

  42.   

    哈!
    楼上的一语道破啊!
    编译之后的程序果然能够看到showmessage中的内容!
    原来在编译的时候继续按F9就可以运行下去了……
    唉,
    从来都是看到报错就Ctrl+F2的……多谢多谢啊!
      

  43.   

    呵呵!
    终于可以圆满的结帖了!
    学习到了新东西,
    也麻烦各位查找了那么多的东西!
    特别是  chijingde(AD) ,查找了那么多的程序!
    这个帖子还是很值得继续慢慢看看滴!