Заметки
DirectoryExists и ее вечное True

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика


1. Предисловие.

Была поставлена задача. Есть список каталогов (мапированные вида z:\arc и сетевые \\server\\arc). Надо сделать сервис открытия каталога. Сделано было в две строчки:

if DirectoryExists(fs) then
  ShellExecute(Application.handle,nil,'explorer.exe',PWideChar(fs),nil,SW_SHOWNORMAL);

Было это во времена Delphi 7 и Windows XP.

2. Предисловие.

Но время шло и когда мы перешли на Delphi XE2 и Windows 7, от пользователя поступила претензия: «Когда пытаешься открыть папку, к которой у текущего пользователя нет прав, открывается папку мои документы».

3. Потуги.

Поиски причины такого поведения привели в:

// System.SysUtils
{...}
function DirectoryExists(const Directory: string; FollowLink: Boolean = True): Boolean;
{$IFDEF MSWINDOWS}
var
  Code: Cardinal;
  Handle: THandle;
  LastError: Cardinal;
begin
  Result := False;
  Code := GetFileAttributes(PChar(Directory));

  if Code <> INVALID_FILE_ATTRIBUTES then
  begin
    {...}
  end
  else
  begin
    LastError := GetLastError;
    Result := (LastError <> ERROR_FILE_NOT_FOUND) and
      (LastError <> ERROR_PATH_NOT_FOUND) and
      (LastError <> ERROR_INVALID_NAME) and
      (LastError <> ERROR_BAD_NETPATH);
  end;
end;
{$ENDIF MSWINDOWS}

А вот это уже интересно! Получается, что даже если GetFileAttributes вернул INVALID_FILE_ATTRIBUTES - это не значит что функция вернет False. Так как дальше происходит анализ GetLastError, которая в моем случаи возвращает ERROR_BAD_NET_NAME, а это значение не обрабатывается. И в результате функция DirectoryExists возвращает True.

4. Happy end.

В данном случаи я решил проблему добавлением условия в свою программу

if DirectoryExists(fs) and not (
  (GetFileAttributes(PChar(fs)) = INVALID_FILE_ATTRIBUTES) and (GetLastError = ERROR_BAD_NET_NAME)
  ) then
ShellExecute(Application.handle,nil,'explorer.exe',PWideChar(fs),nil,SW_SHOWNORMAL);

Автор: Thunderchild.

P.S.

В XE6 и выше эта ошибка устранена, проверить на других версиях нет возможности.

При использовании материала - ссылка на сайт обязательна