none
フォルダのMoveFile で「ERROR_ACCESS_DENIED(アクセスが拒否)」エラーとなる RRS feed

  • 質問

  • Explorerで下位フォルダを開いていると上位フォルダの MoveFile で「ERROR_ACCESS_DENIED(アクセス拒否)」のエラーとなります。

    具体的には、

    testfolder

     +- subfolder

    のフォルダがあり、Explorer で subfolder を開いておきます。

    この状態で、testfolderのMoveFileを実行すると、エラーとなります。(MoveFileExでもエラーとなりました)

    Explorerで一つ上のtestfolderに移動した後(subfolderを開いていない状態)、MoveFileを実行すると、正常に testfolderがリネームされます。

    MoveFileでなくSHFileOperationを使用すればエラーは発生しないという記事を見ましたが、ウィンドウを持たないプログラムなのでこの関数は使用できません。

    どなたが解決策をご存じの方がいらっしゃいましたらご教授ください。

    2013年1月17日 2:33

回答

  • 直接の解決策ではありませんが...、

    MoveFileでなくSHFileOperationを使用すればエラーは発生しないという記事を見ましたが、ウィンドウを持たないプログラムなのでこの関数は使用できません。


    ウィンドウを持たないプログラムから Shell API を使用できない、ということはないはずです。
    セッション 0 に分離された Windows サービスの類のように、ユーザーと対話できないプロセスだと具合が悪いと思いますが。
    • 回答としてマーク HiroXXX 2013年1月17日 12:19
    2013年1月17日 6:01

すべての返信

  • Explorerに限りません。例えばコマンドプロンプトを開き、カレントディレクトリをtestfolderにした上で、MoveFileを実行すると、同様にエラーになるはずです。
    要するに何らかのプログラムが当該ディレクトリもしくはそのサブディレクトリをカレントディレクトリに指定している場合、MoveFileできません。

    そこで質問ですが、Explorerが開いている場合にだけに対処したいという質問でしょうか?

    2013年1月17日 2:46
  • Explorlerが開いている場合だけに対処できれば良いです。

    OSの一部とも言えるExplorerがただフォルダを開いているだけなのにフォルダのリネームができないというのがよろしくないという考えです。よろしくお願いいたします。

    2013年1月17日 5:13
  • 直接の解決策ではありませんが...、

    MoveFileでなくSHFileOperationを使用すればエラーは発生しないという記事を見ましたが、ウィンドウを持たないプログラムなのでこの関数は使用できません。


    ウィンドウを持たないプログラムから Shell API を使用できない、ということはないはずです。
    セッション 0 に分離された Windows サービスの類のように、ユーザーと対話できないプロセスだと具合が悪いと思いますが。
    • 回答としてマーク HiroXXX 2013年1月17日 12:19
    2013年1月17日 6:01
  • SHFileOperationを使用するにはウィンドウハンドル(HWND)が必要になると思いますが、これをどこから取ってくるのかで試行錯誤した経緯があります。HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName) で取得できそうですが、どのクラス名、タイトル名を指定したものか、わかりませんでした。これが解決できれば、SHFileOperationを使用して解決、となるのですが。。。

    2013年1月17日 10:07
  • 渡すべきウィンドウ ハンドルがないのであれば、NULL とか HWND_DESKTOP とか (同じ値ですが) にしてはいかがでしょうか。

    • 回答としてマーク HiroXXX 2013年1月17日 12:18
    • 回答としてマークされていない HiroXXX 2013年1月17日 12:19
    2013年1月17日 10:27
  • ウィンドウハンドルをNULLにして失敗していたと思ったのですが、再度試してみたところ、SHFileOperationで問題なくリネームができました。大変ありがとうございました。以下が確認したソースです。

      SHFILEOPSTRUCT fop = {0};
      fop.hwnd = NULL;
      fop.wFunc = FO_MOVE;
      fop.fFlags = FOF_SILENT;
      fop.pFrom = _T("C:\\Users\\user-name\\Documents\\testfolder");
      fop.pTo = _T("C:\\Users\\user-name\\Documents\\testfolder_new)";
      int ret = SHFileOperation(&fop);


    • 編集済み HiroXXX 2013年1月17日 12:21
    2013年1月17日 12:18
  • 本筋ではありませんが、念のため。

    FindWindow はすでに作成されているウィンドウを探すためのものです。
    SHFileOpeartion が求めているのは "A window handle to the dialog box to display information about the status of the file operation." ですので、自分があずかり知らないウィンドウハンドルを渡してはいけません。

    2013年1月17日 13:04
    モデレータ
  • ウィンドウハンドルをNULLにして失敗していたと思ったのですが、再度試してみたところ、SHFileOperationで問題なくリネームができました。大変ありがとうございました。以下が確認したソースです。

      SHFILEOPSTRUCT fop = {0};
      fop.hwnd = NULL;
      fop.wFunc = FO_MOVE;
      fop.fFlags = FOF_SILENT;
      fop.pFrom = _T("C:\\Users\\user-name\\Documents\\testfolder");
      fop.pTo = _T("C:\\Users\\user-name\\Documents\\testfolder_new)";
      int ret = SHFileOperation(&fop);



    pFrom と pTo は "This string must be double-null terminated." なので、'¥0' を 2 個続けてバッファの終わりを教えてあげないといけないはずです。
    成功したり失敗したり動きが不安定なのは、そのせいではないかと。
    (今回はたまたま成功してしまっただけで、同じコードでも失敗する可能性はあります。)

    SHFILEOPSTRUCT structure (Windows)
    http://msdn.microsoft.com/en-us/library/bb759795(VS.85).aspx
    2013年1月17日 16:18