DirectoryExistsが全てTrueを返してしまう

解決


ナベ  2013-04-09 02:09:02  No: 44222

OS    :Windows7ProSP1 64bit
Delphi:XE2 バージョン 16.0.4429.46931

上記環境で下記DirectoryExistsを実行すると存在しない共有フォルダを指定してもTrueが返ってきます。

if DirectoryExists('共有フォルダ') then
  ShowMessage('OK')
else
  ShowMessage('NG');

'共有フォルダ'に存在するフォルダ('\\192.168.XXX.XXX\test')を指定した場合は'OK'が表示されますが、
存在しないフォルダ('\\192.168.XXX.XXX\testABC')を指定しても'OK'が表示されます。

なお、このコードの実行ファイルを別のネットワーク環境のXPで実行すると正常に動作します。
ただし、別のネットワーク環境のWin7では全てTrueが返ってきてしまいます。

ためしにWinXPSP3のTurboDelphiで作成した実行ファイルをWin7環境で実行した場合は正常に動作しました。

どうも環境のような気がしますが、いろいろ調べても解決せず困っています。
何かお気づきの方がいらっしゃいましたら、何卒ご教授の程、よろしくお願い致します。


KHE00221  2013-04-09 05:50:07  No: 44223

DirectoryExists の LastError := GetLastError; で

LastError に ERROR_ACCESS_DENIED が返って来るけど

  Result := (LastError <> ERROR_FILE_NOT_FOUND) and
      (LastError <> ERROR_PATH_NOT_FOUND) and
      (LastError <> ERROR_INVALID_NAME) and
      (LastError <> ERROR_BAD_NETPATH);

にないから

and (LastError <> ERROR_ACCESS_DENIED) を追加すれば OK


ナベ  2013-04-09 19:09:16  No: 44224

返答頂き有難うございます。

私の環境でLastErrorを取得したところ、ERROR_BAD_NET_NAMEでした。
たしかにDirectoryExistsのコードを見ると

  Result := (LastError <> ERROR_FILE_NOT_FOUND) and
      (LastError <> ERROR_PATH_NOT_FOUND) and
      (LastError <> ERROR_INVALID_NAME) and
      (LastError <> ERROR_BAD_NETPATH);

となっていますので、今後別の環境によって違うエラーが発生する事も考えると、
単純にLastErrorがNO_ERRORかどうかで判断しようと思います。

if LastErr = NO_ERROR then
  ShowMessage('OK')
else
  ShowMessage('NG');

今のところ、上記コードで上手く判断する事が出来ました。
誠に有難うございました。


ナベ  2013-04-11 03:22:47  No: 44225

自己レスです。

別のネットワーク環境で試したところ、今度は存在する共有フォルダに対してエラーとなってしまいました。
GetLastErrorでエラーコードを調べたところ、ERROR_INVALID_PARAMETERのエラーでしたので、NO_ERRORだけでの判断ではダメでした。

結局、DirectoryExistsのコードを修正する方法しかないのかと思いましたが、TurboDelphi(Delphi2006)では
問題なく動作する為、XE2のDirectoryExistsとTurboDelphiのDirectoryExistsのコードを調べたところ、
XE2とTurboDelphiとでは、中身が全然別物となっていました。

■XE2
function DirectoryExists(const Directory: string; FollowLink: Boolean = True): Boolean;
var
  Code: Cardinal;
  Handle: THandle;
  LastError: Cardinal;
begin
  Result := False;
  Code := GetFileAttributes(PChar(Directory));

  if Code <> INVALID_FILE_ATTRIBUTES then
  begin
    if faSymLink and Code = 0 then
      Result := faDirectory and Code <> 0
    else
    begin
      if FollowLink then
      begin
        Handle := CreateFile(PChar(Directory), GENERIC_READ, FILE_SHARE_READ, nil,
          OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
        if Handle <> INVALID_HANDLE_VALUE then
        begin
          CloseHandle(Handle);
          Result := faDirectory and Code <> 0;
        end;
      end
      else if faDirectory and Code <> 0 then
        Result := True
      else
      begin
        Handle := CreateFile(PChar(Directory), GENERIC_READ, FILE_SHARE_READ, nil,
          OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
        if Handle <> INVALID_HANDLE_VALUE then
        begin
          CloseHandle(Handle);
          Result := False;
        end
        else
          Result := True;
      end;
    end;
  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;

■TurboDelphi
function DirectoryExists(const Directory: string): Boolean;
var
  Code: Integer;
begin
  Code := GetFileAttributes(PChar(Directory));
  Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;

最終的にはTurboDelphiのDirectoryExistsのコードをXE2で使用したところ、問題なく共有フォルダのチェックが出来る様になりました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加