Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi External Exception (https://www.delphipraxis.net/36332-external-exception.html)

Luckie 18. Dez 2004 15:19


External Exception
 
Ich hatte folgenden Code:
Delphi-Quellcode:
procedure LoadLogicalDrives(Strings: TStrings; ReadyOnly: Boolean = True;
  WithLabels: Boolean = True);

  function DriveIsReady(Drive: string): Boolean;
  var
    i         : Integer;
    sRec      : TSearchRec;
  begin
    SetErrorMode(SEM_FAILCRITICALERRORS);
    i := FindFirst(Drive + '*.*', faAnyFile, sRec);
    if i = 0 then
    begin
      Result := True;
    end
    else
    begin
      Result := False;
    end;
    FindClose(sRec);
    SetErrorMode(0);
  end;

var
  s           : DWORD;
  AllStrings  : PChar;
  CurrentString: PChar;
begin
  s := 255;
  GetMem(AllStrings, Succ(s));
  GetLogicalDriveStrings(S, AllStrings);
  try
    if AllStrings <> nil then
    begin
      CurrentString := AllStrings;
      while CurrentString[0] <> #0  do
      begin
        if (DriveIsReady(StrPas(CurrentString))) and ReadyOnly then
        begin
          if WithLabels then
            Strings.Add(StrPas(CurrentString)+' ['+GetVolumelabel(CurrentString)+']')
          else
            Strings.Add(StrPas(CurrentString));
        end;
        Inc(CurrentString, Succ(StrLen(CurrentString)));
      end;
    end;
  finally
    FreeMem(AllStrings);
  end;
end;
Jetzt wollte ich erst mal das FindFile loswerden und habe entsprechend FindFikles benutzt. dann sieht das so aus:
Delphi-Quellcode:
procedure LoadLogicalDrives(var Drives: TStringArray; ReadyOnly: Boolean = True;
  WithLabels: Boolean = True);

  function DriveIsReady(const Drive: string): Boolean;
  var
    wfd       : TWin32FindData;
    hFindData : THandle;
  begin
    SetErrorMode(SEM_FAILCRITICALERRORS);
    hFindData := FindFirstFile(Pointer(Drive + '*.*'), wfd);
    if hFindData <> INVALID_HANDLE_VALUE then
    begin
      Result := True;
    end
    else
    begin
      Result := False;
    end;
    CloseHandle(hFindData);
    SetErrorMode(0);
  end;

var
  s           : DWORD;
  AllStrings  : PChar;
  CurrentString: PChar;
  cntDrives: Integer;
begin
  s := 255;
  cntDrives := 0;
  SetLength(Drives, 26);
  GetMem(AllStrings, Succ(s));
  GetLogicalDriveStrings(S, AllStrings);
  try
    if AllStrings <> nil then
    begin
      CurrentString := AllStrings;
      while CurrentString[0] <> #0 do
      begin
        if ReadyOnly then
        begin
          if (DriveIsReady(StrPas(CurrentString))) then
          begin
            if WithLabels then
              Drives[cntDrives] := String(CurrentString)+ ' ['+GetVolumeLabel(currentString)+']'
            else
              Drives[cntDrives] := String(StrPas(CurrentString));
            Inc(cntDrives);
          end;
        end
        else
        begin
          if WithLabels then
            Drives[cntDrives] := String(CurrentString) + ' [' +
              GetVolumelabel(CurrentString) + ']'
          else
            Drives[cntDrives] := String(CurrentString);
          Inc(cntDrives);
        end;
        Inc(CurrentString, Succ(StrLen(CurrentString)));
      end;
    end;
  finally
    SetLength(Drives, cntDrives);
    FreeMem(AllStrings);
  end;
end;
Nur passiert jetzt das Dumme, dass er nach dem zweiten Laufwerk, das er findet, bei mir C:\, aus der Schleife rausgeht und nach FreeMem(AllStrings) springt und dann kommt es zu einer External Exception - was auch immer das heißen mag. :gruebel:

Weiß da jemand Rat?

omata 18. Dez 2004 16:53

Re: External Exception
 
Moin,

für FindFirstFile muss Windows.FindClose(Handle) anstatt CloseHandle(Handle) benutzen werden.

DriveIsReady muss also so aussehen...
Delphi-Quellcode:
  function DriveIsReady(const Drive: string): Boolean;
  var
    wfd       : TWin32FindData;
    hFindData : THandle;
  begin
    SetErrorMode(SEM_FAILCRITICALERRORS);
    hFindData := FindFirstFile(Pointer(Drive + '*.*'), wfd);
    Result := (hFindData <> INVALID_HANDLE_VALUE);
    if Result then
      Windows.FindClose(hFindData);
    SetErrorMode(0);
  end;
ich habe da gleich mal die IF-Anweisung rausgeschmissen (war schlechter Stil)

MfG
Thorsten

Edit: Das FindClose wird nur noch ausgeführt, wenn das Handle gültig ist (liefert intern nicht mehr soviele Fehler)

Luckie 18. Dez 2004 18:57

Re: External Exception
 
Danke, das war es.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz