フォルダ自体の情報を取得するには?

解決


arigayas  URL  2013-03-21 18:15:24  No: 44081

ファイルをダウンロードするソフトをDelphi XE Professional版+Win7で作っています。

ダウンロードフォルダに書き込み権限のないフォルダを指定されても
エラーメッセージとして「書き込み権限のないフォルダのため選びなおしてください」と出して
ダウンロードフォルダとして指定させないようにするにはどうすれば良いでしょうか?


take  2013-03-21 19:07:35  No: 44082

指定させないことは出来ないかもしれないけど
書き込めないフォルダが指定さてたかどうかの判定は出来るから
そこから指定させ直すとかは?

テキストエディタで記述しただけだから
コンパイル通るかは不明だけど

  attr := GetFileAttributes(PChar(FileName)); 
  if Bool(attr and FILE_ATTRIBUTE_READONLY) then begin
    /* 読み込み専用だからダメよ */
    exit;
  end;
  /* 書き込めそうだから書き込み処理へ */


DEKO  2013-03-21 19:47:45  No: 44083

結局の所、実際に書き込んで試してみないとダメだった記憶があります。

↓こんな感じの関数作って、

function IsWritableFolder(aPath: string): Boolean;
var
  hFile: THandle;
  dFileName: String;
begin
  result := False;
  if not DirectoryExists(aPath) then
    Exit;
  dFileName := IncludeTrailingPathDelimiter(aPath) + 'writablecheck.temporary';
  UniqueString(dFileName);
  hFile := CreateFile(PChar(dFileName), GENERIC_WRITE, 0, nil, CREATE_ALWAYS,
             FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0);
  result := (hFile <> INVALID_HANDLE_VALUE);
  if result then
    CloseHandle(hFile);
end;

↓こんな感じで使います。

procedure TForm1.Button1Click(Sender: TObject);
const
  MSG: array [Boolean] of string = ('書き込めないよ...orz', '書き込めるよ (^o^)/');
begin
  // Edit1 に入力されたパスに対して書き込み可能か調べる
  ShowMessage(MSG[IsWritableFolder(Edit1.Text)]);
end;


arigayas  URL  2013-03-22 17:43:55  No: 44084

take さん、DEKO さん返信ありがとうございます。

take さんの記述方法でコンパイルは通ったのですが、
システムフォルダのごみ箱(C:\$Recycle.Bin)を指定した場合に「書き込めるよ」ってなってしまいました・・・。

DEKO さんの「function IsWritableFolder」で思い通りの処理ができました。
ありがとうございます。


arigayas  2013-03-22 17:45:12  No: 44085

解決のチェック入れ忘れました(汗)


DEKO  2013-03-22 18:40:01  No: 44086

補足しときますと、
ちゃんと権限を調べて書き込みチェックをやろうとした場合、

・特権が必要となる。
・管理者権限が必要となる。

確かどっちかの問題で挫折しました。

「鶏が先か卵が先か」って話になって、
最終的に "実際に書き込んでテストするしかない" という
結論に至ったのだったと記憶しています。

# 試行錯誤したプロジェクトがどっかに残っていないかと
# 探してみましたが見当たりませんでした...残念。


arigayas  2013-03-23 08:14:45  No: 44087

DEKO さん、そういうことだったんですね。

    if not DirectoryExists(aPath) then
のままコンパイルすると
[DCC 警告] ほげほげ.pas(409): W1000: シンボル 'DirectoryExists' を使用することは推奨されていません :
 'Use SysUtils.DirectoryExists instead'
と出たので
    if not SysUtils.DirectoryExists (aPath) then
と書き換えました。
報告までに。


DEKO  2013-03-23 10:04:34  No: 44088

> [DCC 警告] ほげほげ.pas(409): W1000: シンボル 'DirectoryExists' を使用することは推奨されていません :
> 'Use SysUtils.DirectoryExists instead'

そうですね。

丁度触っていたのが Delphi 2007 だったので気付きませんでしたが、
(Delphi 2007 ではワーニングになりません)
ワーニングが出た場合にはメッセージに従って素直に修正した方がいいです。

...もっとも、XE2 / XE3 でこの修正をやってしまうと、名前空間が異なるので、
それ以前の Delphi ではエラーになるコードになってしまいますが。

# バージョン依存なコードは書きたくないので、バージョン固有の問題でない限り、
# できるだけ古い Delphi でも動作するコードを書くようにしています。


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

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






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