0

すべての構造を持つフォルダーを再帰的に削除するコードを作成しました。

から取得System.IO.DirectoryNotFoundExceptionFile.Deleteた有効なファイル名を取得しましたDirectory.GetFiles(path)。以前に追加File.Existsしたところ、ファイルが存在しないか、エクスプローラーで表示できることがわかりました。

私はそれがうまくいくSHFileOperationはずだと知っています。しかし、ネイティブ C# を使用したいと思います (直接の Windows API ではありません)。

赤: Windows 10 で .NET 4.6.2 と長いパスを設定し、ローカル グループ ポリシー エディターで [Win 32 の長いパスを有効にする] を有効にします。

.NET Framework 4.7.2 を使用しています。

私のコードの何が問題なのか誰か教えてもらえますか? または、それを機能させるために何ができますか?

エラーのパスは次のとおりです。

「E:\CobianBackupOld\cn1629\AppData\Local\Packages\Microsoft.Windows.Cortana_cw5n1h2txyewy\LocalState\AppIconCache\100\{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}_Microsoft Visual Studio 9_0_Application_PreEmptive Solutions_Dotfuscator Community Edition_dotfuscator_exe」

私はそのファイルの所有者です (ファイルを削除する権限があります)。

アップデート

エラーを部分的に修正しましたが、適切に修正する方法を知りたいです (最近のフレームワークは長いパスをサポートしていると思われますか???)。私の実際の修正は、再帰関数の開始時にそのコードを追加することです

if (path.Length < 2 || !path.StartsWith(@"\\"))
{
  path = @"\\?\" + path;
}

更新 2 直接関係はありませんが... 重要な点を説明したいのですが、C# File.Delete または Directory.Delete は読み取り専用のファイルまたはフォルダーを削除しません。削除する前に、アクセス許可を通常に変更する必要があります。そうしないと、アクセス権が取得されます。拒否エラー。

参考までに、私のコードは次のとおりです。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HQ.Util.General.IO
{
    public class DirectoryRemoverRecursive
    {
        private readonly Action<string, string> _pathStatus;
        private readonly Func<string, bool> _callbackCanRemoveFile;
        private readonly Func<string, bool> _callbackCanRemoveFolder;
        private Func<bool> _shouldCancel;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pathStatus">Arguments are [path] and [null on success or exception message]</param>
        /// <param name="callbackCanRemoveFile">Argument is path and should return true to delete. If this function is null, all path will be deleted.</param>
        /// <param name="callbackCanRemoveFolder">Argument is path and should return true to delete. If this function is null, all path will be deleted.</param>
        /// <param name="shouldCancel">If null will never cancel. Cancel when func return true</param>
        public DirectoryRemoverRecursive(
            Action<string, string> pathStatus = null, 
            Func<string, bool> callbackCanRemoveFile = null, 
            Func<string, bool> callbackCanRemoveFolder = null, 
            Func<bool> shouldCancel = null)
        {
            _pathStatus = pathStatus;
            _callbackCanRemoveFile = callbackCanRemoveFile;
            _callbackCanRemoveFolder = callbackCanRemoveFolder;
            _shouldCancel = shouldCancel;
        }

        // ******************************************************************
        /// <summary>
        /// return true if canceled
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public bool Remove(string path)
        {
            string result = null;

            if (Directory.Exists(path))
            {
                foreach (var subDir in Directory.GetDirectories(path))
                {
                    if (_shouldCancel != null)
                    {
                        if (_shouldCancel())
                        {
                            return true;
                        }
                    }

                    if (Remove(subDir))
                    {
                        return true;
                    }
                }

                foreach (var filename in Directory.GetFiles(path))
                {
                    if (_shouldCancel != null)
                    {
                        if (_shouldCancel())
                        {
                            return true;
                        }
                    }

                    if (Remove(filename))
                    {
                        return true;
                    }
                }

                try
                {
                    if (_callbackCanRemoveFolder != null)
                    {
                        if (!_callbackCanRemoveFolder(path))
                        {
                            return false;
                        }
                    }

                    Directory.Delete(path);
                    result = null;
                }
                catch (Exception ex)
                {
                    result = ex.Message;
                }
            }
            else
            {
                try
                {
                    if (File.Exists(path))
                    {
                        if (_callbackCanRemoveFile != null)
                        {
                            if (!_callbackCanRemoveFile(path))
                            {
                                return false;
                            }
                        }

                        File.Delete(path);
                        result = null;
                    }
                    else
                    {
                        Debug.Print($"File does not exists {path}");
                    }
                }
                catch (Exception ex)
                {
                    result = ex.Message;
                }
            }

            _pathStatus?.Invoke(path, result);

            return false;
        }

        // ******************************************************************

    }

}
4

1 に答える 1