Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/duplicati/duplicati.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Duplicati/Library/Main/Controller.cs49
-rw-r--r--Duplicati/Library/Main/Operation/BackupHandler.cs8
-rw-r--r--Duplicati/Library/Main/Options.cs8
-rw-r--r--Duplicati/Library/Main/Strings/Controller.Designer.cs31
-rw-r--r--Duplicati/Library/Main/Strings/Controller.resx11
-rw-r--r--Duplicati/Library/Main/Strings/Options.Designer.cs12
-rw-r--r--Duplicati/Library/Main/Strings/Options.resx8
-rw-r--r--Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj2
-rw-r--r--Duplicati/Library/Snapshots/LinuxSnapshot.cs6
-rw-r--r--Duplicati/Library/Snapshots/NoSnapshot.cs16
-rw-r--r--Duplicati/Library/Snapshots/NoSnapshotWindows.cs8
-rw-r--r--Duplicati/Library/Snapshots/WindowsSnapshot.cs2
-rw-r--r--Duplicati/Library/Utility/Utility.cs173
13 files changed, 165 insertions, 169 deletions
diff --git a/Duplicati/Library/Main/Controller.cs b/Duplicati/Library/Main/Controller.cs
index 0b3e8bda8..94504c221 100644
--- a/Duplicati/Library/Main/Controller.cs
+++ b/Duplicati/Library/Main/Controller.cs
@@ -65,48 +65,59 @@ namespace Duplicati.Library.Main
m_options = new Options(options);
}
- public Duplicati.Library.Interface.IBackupResults Backup(string[] sources, IFilter filter = null)
+ public Duplicati.Library.Interface.IBackupResults Backup(string[] inputsources, IFilter filter = null)
{
- return RunAction(new BackupResults(), ref sources, (result) => {
+ return RunAction(new BackupResults(), ref inputsources, (result) => {
- if (sources == null || sources.Length == 0)
+ if (inputsources == null || inputsources.Length == 0)
throw new Exception(Strings.Controller.NoSourceFoldersError);
+ var sources = new List<string>(inputsources);
+
//Make sure they all have the same format and exist
- for(int i = 0; i < sources.Length; i++)
+ for(int i = 0; i < sources.Count; i++)
{
- string fp;
try
{
- fp = System.IO.Path.GetFullPath(sources[i]);
+ sources[i] = System.IO.Path.GetFullPath(sources[i]);
}
catch (Exception ex)
{
throw new ArgumentException(string.Format(Strings.Controller.InvalidPathError, sources[i], ex.Message), ex);
}
- sources[i] = Library.Utility.Utility.AppendDirSeparator(fp);
-
- if (!System.IO.Directory.Exists(sources[i]) && !m_options.AllowMissingSourceFolders)
- throw new System.IO.IOException(String.Format(Strings.Controller.SourceFolderIsMissingError, sources[i]));
+ var fi = new System.IO.FileInfo(sources[i]);
+ var di = new System.IO.DirectoryInfo(sources[i]);
+ if (!(fi.Exists || di.Exists) && !m_options.AllowMissingSource)
+ throw new System.IO.IOException(String.Format(Strings.Controller.SourceIsMissingError, sources[i]));
+
+ if (!fi.Exists)
+ sources[i] = Library.Utility.Utility.AppendDirSeparator(sources[i]);
}
//Sanity check for duplicate folders and multiple inclusions of the same folder
-
- //We could automatically fix this by excluding multiple copies of the same folder
- // and remove the longest path of matching subfolders,
- // but really the user should clean up the input
- for(int i = 0; i < sources.Length - 1; i++)
+ for(int i = 0; i < sources.Count - 1; i++)
{
- for(int j = i + 1; j < sources.Length; j++)
+ for(int j = i + 1; j < sources.Count; j++)
if (sources[i].Equals(sources[j], Library.Utility.Utility.IsFSCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase))
- throw new Exception(string.Format(Strings.Controller.SourceDirIsIncludedMultipleTimesError, sources[i]));
+ {
+ result.AddVerboseMessage("Removing duplicate source: {0}", sources[j]);
+ sources.RemoveAt(j);
+ j--;
+ }
else if (sources[i].StartsWith(sources[j], Library.Utility.Utility.IsFSCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase))
- throw new Exception(string.Format(Strings.Controller.SourceDirsAreRelatedError, sources[i], sources[j]));
+ {
+ result.AddVerboseMessage("Removing source \"{0}\" because it is a subfolder of \"{1}\"", sources[i], sources[j]);
+ filter = Library.Utility.JoinedFilterExpression.Join(new FilterExpression(sources[i]), filter);
+
+ sources.RemoveAt(i);
+ i--;
+ break;
+ }
}
using(var h = new Operation.BackupHandler(m_backend, m_options, result))
- h.Run(sources, filter);
+ h.Run(sources.ToArray(), filter);
});
}
diff --git a/Duplicati/Library/Main/Operation/BackupHandler.cs b/Duplicati/Library/Main/Operation/BackupHandler.cs
index 8abd9d3a9..942c142a5 100644
--- a/Duplicati/Library/Main/Operation/BackupHandler.cs
+++ b/Duplicati/Library/Main/Operation/BackupHandler.cs
@@ -65,12 +65,12 @@ namespace Duplicati.Library.Main.Operation
throw new Exception(string.Format(Strings.Foresthash.InvalidCryptoSystem, m_options.FileHashAlgorithm));
}
- private static Snapshots.ISnapshotService GetSnapshot(string[] sourcefolders, Options options, ILogWriter log)
+ private static Snapshots.ISnapshotService GetSnapshot(string[] sources, Options options, ILogWriter log)
{
try
{
if (options.SnapShotStrategy != Options.OptimizationStrategy.Off)
- return Duplicati.Library.Snapshots.SnapshotUtility.CreateSnapshot(sourcefolders, options.RawOptions);
+ return Duplicati.Library.Snapshots.SnapshotUtility.CreateSnapshot(sources, options.RawOptions);
}
catch (Exception ex)
{
@@ -83,9 +83,9 @@ namespace Duplicati.Library.Main.Operation
}
return Library.Utility.Utility.IsClientLinux ?
- (Library.Snapshots.ISnapshotService)new Duplicati.Library.Snapshots.NoSnapshotLinux(sourcefolders, options.RawOptions)
+ (Library.Snapshots.ISnapshotService)new Duplicati.Library.Snapshots.NoSnapshotLinux(sources, options.RawOptions)
:
- (Library.Snapshots.ISnapshotService)new Duplicati.Library.Snapshots.NoSnapshotWindows(sourcefolders, options.RawOptions);
+ (Library.Snapshots.ISnapshotService)new Duplicati.Library.Snapshots.NoSnapshotWindows(sources, options.RawOptions);
}
diff --git a/Duplicati/Library/Main/Options.cs b/Duplicati/Library/Main/Options.cs
index deb598956..2fb8bf789 100644
--- a/Duplicati/Library/Main/Options.cs
+++ b/Duplicati/Library/Main/Options.cs
@@ -187,7 +187,7 @@ namespace Duplicati.Library.Main
"disable-autocreate-folder",
"disable-filetime-check",
"disable-time-tolerance",
- "allow-missing-source-folders",
+ "allow-missing-source",
"skip-files-larger-than",
"upload-unchanged-backups",
"list-verify-uploads",
@@ -348,7 +348,7 @@ namespace Duplicati.Library.Main
new CommandLineArgument("version", CommandLineArgument.ArgumentType.String, Strings.Options.VersionShort, Strings.Options.VersionLong, ""),
new CommandLineArgument("all-versions", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllversionsShort, Strings.Options.AllversionsLong, "false"),
new CommandLineArgument("disable-autocreate-folder", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisableautocreatefolderShort, Strings.Options.DisableautocreatefolderLong, "false"),
- new CommandLineArgument("allow-missing-source-folders", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllowmissingsourcefoldersShort, Strings.Options.AllowmissingsourcefoldersLong, "false"),
+ new CommandLineArgument("allow-missing-source", CommandLineArgument.ArgumentType.Boolean, Strings.Options.AllowmissingsourceShort, Strings.Options.AllowmissingsourceLong, "false"),
new CommandLineArgument("disable-filetime-check", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisablefiletimecheckShort, Strings.Options.DisablefiletimecheckLong, "false"),
//new CommandLineArgument("disable-usn-diff-check", CommandLineArgument.ArgumentType.Boolean, Strings.Options.DisableusndiffcheckShort, Strings.Options.DisableusndiffcheckLong, "false"),
@@ -1385,9 +1385,9 @@ namespace Duplicati.Library.Main
/// <summary>
/// Gets a flag indicating if compacting should not be done automatically
/// </summary>
- public bool AllowMissingSourceFolders
+ public bool AllowMissingSource
{
- get { return Library.Utility.Utility.ParseBoolOption(m_options, "allow-missing-source-folders"); }
+ get { return Library.Utility.Utility.ParseBoolOption(m_options, "allow-missing-source"); }
}
/// <summary>
diff --git a/Duplicati/Library/Main/Strings/Controller.Designer.cs b/Duplicati/Library/Main/Strings/Controller.Designer.cs
index 426d8ff6a..e098fc842 100644
--- a/Duplicati/Library/Main/Strings/Controller.Designer.cs
+++ b/Duplicati/Library/Main/Strings/Controller.Designer.cs
@@ -556,38 +556,11 @@ namespace Duplicati.Library.Main.Strings {
}
/// <summary>
- /// Looks up a localized string similar to The folder {0} is included multiple times.
- /// </summary>
- internal static string SourceDirIsIncludedMultipleTimesError {
- get {
- return ResourceManager.GetString("SourceDirIsIncludedMultipleTimesError", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The folder {1} is a subfolder of {0}. It is not allowed to specify the same folder multiple times..
- /// </summary>
- internal static string SourceDirsAreRelatedError {
- get {
- return ResourceManager.GetString("SourceDirsAreRelatedError", resourceCulture);
- }
- }
-
- /// <summary>
/// Looks up a localized string similar to The source folder {0} does not exist, aborting backup.
/// </summary>
- internal static string SourceFolderIsMissingError {
- get {
- return ResourceManager.GetString("SourceFolderIsMissingError", resourceCulture);
- }
- }
-
- /// <summary>
- /// Looks up a localized string similar to The folder {0} is no longer in the source folder set. It is not allowed to change source folders for a backup..
- /// </summary>
- internal static string SourceFoldersHasChangedError {
+ internal static string SourceIsMissingError {
get {
- return ResourceManager.GetString("SourceFoldersHasChangedError", resourceCulture);
+ return ResourceManager.GetString("SourceIsMissingError", resourceCulture);
}
}
diff --git a/Duplicati/Library/Main/Strings/Controller.resx b/Duplicati/Library/Main/Strings/Controller.resx
index 4fd635b6e..d88fcec6b 100644
--- a/Duplicati/Library/Main/Strings/Controller.resx
+++ b/Duplicati/Library/Main/Strings/Controller.resx
@@ -195,18 +195,9 @@
<data name="SkippedUnlistedSignatureFileWarning" xml:space="preserve">
<value>The signature file {0} was skipped because the signature file was not found in the manifest</value>
</data>
- <data name="SourceDirIsIncludedMultipleTimesError" xml:space="preserve">
- <value>The folder {0} is included multiple times</value>
- </data>
- <data name="SourceDirsAreRelatedError" xml:space="preserve">
- <value>The folder {1} is a subfolder of {0}. It is not allowed to specify the same folder multiple times.</value>
- </data>
- <data name="SourceFolderIsMissingError" xml:space="preserve">
+ <data name="SourceIsMissingError" xml:space="preserve">
<value>The source folder {0} does not exist, aborting backup</value>
</data>
- <data name="SourceFoldersHasChangedError" xml:space="preserve">
- <value>The folder {0} is no longer in the source folder set. It is not allowed to change source folders for a backup.</value>
- </data>
<data name="StatusBuildingFilelist" xml:space="preserve">
<value>Building filelist ...</value>
</data>
diff --git a/Duplicati/Library/Main/Strings/Options.Designer.cs b/Duplicati/Library/Main/Strings/Options.Designer.cs
index 07a42db72..66daf87ae 100644
--- a/Duplicati/Library/Main/Strings/Options.Designer.cs
+++ b/Duplicati/Library/Main/Strings/Options.Designer.cs
@@ -61,20 +61,20 @@ namespace Duplicati.Library.Main.Strings {
}
/// <summary>
- /// Looks up a localized string similar to Use this option to set the timespan in which backups are kept..
+ /// Looks up a localized string similar to Use this option to continue even if some source entries are missing..
/// </summary>
- internal static string AllowmissingsourcefoldersLong {
+ internal static string AllowmissingsourceLong {
get {
- return ResourceManager.GetString("AllowmissingsourcefoldersLong", resourceCulture);
+ return ResourceManager.GetString("AllowmissingsourceLong", resourceCulture);
}
}
/// <summary>
- /// Looks up a localized string similar to Keep all versions within a timespan.
+ /// Looks up a localized string similar to Ignore missing source elements.
/// </summary>
- internal static string AllowmissingsourcefoldersShort {
+ internal static string AllowmissingsourceShort {
get {
- return ResourceManager.GetString("AllowmissingsourcefoldersShort", resourceCulture);
+ return ResourceManager.GetString("AllowmissingsourceShort", resourceCulture);
}
}
diff --git a/Duplicati/Library/Main/Strings/Options.resx b/Duplicati/Library/Main/Strings/Options.resx
index 0cb01abb0..ecf2d0234 100644
--- a/Duplicati/Library/Main/Strings/Options.resx
+++ b/Duplicati/Library/Main/Strings/Options.resx
@@ -540,11 +540,11 @@
<data name="KeeptimeLong" xml:space="preserve">
<value>Use this option to set the timespan in which backups are kept.</value>
</data>
- <data name="AllowmissingsourcefoldersShort" xml:space="preserve">
- <value>Keep all versions within a timespan</value>
+ <data name="AllowmissingsourceShort" xml:space="preserve">
+ <value>Ignore missing source elements</value>
</data>
- <data name="AllowmissingsourcefoldersLong" xml:space="preserve">
- <value>Use this option to set the timespan in which backups are kept.</value>
+ <data name="AllowmissingsourceLong" xml:space="preserve">
+ <value>Use this option to continue even if some source entries are missing.</value>
</data>
<data name="DownloadedFileSizeError" xml:space="preserve">
<value>The file {0} was downloaded and had size {1} but the size was expected to be {2}</value>
diff --git a/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj b/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
index 7c5465e97..86708b640 100644
--- a/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
+++ b/Duplicati/Library/Snapshots/Duplicati.Library.Snapshots.csproj
@@ -48,6 +48,8 @@
<Reference Include="UnixSupport">
<HintPath>..\..\..\thirdparty\UnixSupport\UnixSupport.dll</HintPath>
</Reference>
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="DefineDosDevice.cs" />
diff --git a/Duplicati/Library/Snapshots/LinuxSnapshot.cs b/Duplicati/Library/Snapshots/LinuxSnapshot.cs
index 6f967c3d6..037f22db6 100644
--- a/Duplicati/Library/Snapshots/LinuxSnapshot.cs
+++ b/Duplicati/Library/Snapshots/LinuxSnapshot.cs
@@ -68,7 +68,7 @@ namespace Duplicati.Library.Snapshots
public SnapShot(string path)
{
m_name = string.Format("duplicati-{0}", Guid.NewGuid().ToString());
- m_realDir = Utility.Utility.AppendDirSeparator(path);
+ m_realDir = System.IO.Directory.Exists(path) ? Utility.Utility.AppendDirSeparator(path) : path;
GetVolumeName(m_realDir);
}
@@ -261,7 +261,7 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <param name="folders">The list of folders to create snapshots for</param>
/// <param name="options">A set of commandline options</param>
- public LinuxSnapshot(string[] folders, Dictionary<string, string> options)
+ public LinuxSnapshot(string[] sources, Dictionary<string, string> options)
{
try
{
@@ -269,7 +269,7 @@ namespace Duplicati.Library.Snapshots
//Make sure we do not create more snapshots than we have to
Dictionary<string, SnapShot> snaps = new Dictionary<string, SnapShot>();
- foreach (string s in folders)
+ foreach (string s in sources)
{
SnapShot sn = new SnapShot(s);
if (!snaps.ContainsKey(sn.DeviceName))
diff --git a/Duplicati/Library/Snapshots/NoSnapshot.cs b/Duplicati/Library/Snapshots/NoSnapshot.cs
index 528bb5e37..e9ede2e4e 100644
--- a/Duplicati/Library/Snapshots/NoSnapshot.cs
+++ b/Duplicati/Library/Snapshots/NoSnapshot.cs
@@ -35,7 +35,7 @@ namespace Duplicati.Library.Snapshots
/// <summary>
/// The list of all folders in the snapshot
/// </summary>
- protected string[] m_sourcefolders;
+ protected string[] m_sources;
/// <summary>
/// A frequently used char-as-string
@@ -46,8 +46,8 @@ namespace Duplicati.Library.Snapshots
/// Constructs a new backup snapshot, using all the required disks
/// </summary>
/// <param name="sourcepaths">The folders that are about to be backed up</param>
- public NoSnapshot(string[] folders)
- : this(folders, new Dictionary<string, string>())
+ public NoSnapshot(string[] sources)
+ : this(sources, new Dictionary<string, string>())
{
}
@@ -56,11 +56,11 @@ namespace Duplicati.Library.Snapshots
/// </summary>
/// <param name="folders">The folders that are about to be backed up</param>
/// <param name="options">A set of system options</param>
- public NoSnapshot(string[] folders, Dictionary<string, string> options)
+ public NoSnapshot(string[] sources, Dictionary<string, string> options)
{
- m_sourcefolders = new string[folders.Length];
- for (int i = 0; i < m_sourcefolders.Length; i++)
- m_sourcefolders[i] = Utility.Utility.AppendDirSeparator(folders[i]);
+ m_sources = new string[sources.Length];
+ for (int i = 0; i < m_sources.Length; i++)
+ m_sources[i] = System.IO.Directory.Exists(sources[i]) ? Utility.Utility.AppendDirSeparator(sources[i]) : sources[i];
}
#region Private Methods
@@ -101,7 +101,7 @@ namespace Duplicati.Library.Snapshots
/// <param name="callback">The callback to invoke with each found path</param>
public IEnumerable<string> EnumerateFilesAndFolders(Duplicati.Library.Utility.Utility.EnumerationFilterDelegate callback)
{
- return m_sourcefolders.SelectMany(
+ return m_sources.SelectMany(
s => Utility.Utility.EnumerateFileSystemEntries(s, callback, this.ListFolders, this.ListFiles, this.GetAttributes)
);
}
diff --git a/Duplicati/Library/Snapshots/NoSnapshotWindows.cs b/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
index e6d935358..9635bfce1 100644
--- a/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
+++ b/Duplicati/Library/Snapshots/NoSnapshotWindows.cs
@@ -29,13 +29,13 @@ namespace Duplicati.Library.Snapshots
{
private SystemIOWindows m_sysIO = new SystemIOWindows();
- public NoSnapshotWindows(string[] sourcefolders)
- : base(sourcefolders)
+ public NoSnapshotWindows(string[] sources)
+ : base(sources)
{
}
- public NoSnapshotWindows(string[] sourcefolders, Dictionary<string, string> options)
- : base(sourcefolders, options)
+ public NoSnapshotWindows(string[] sources, Dictionary<string, string> options)
+ : base(sources, options)
{
}
diff --git a/Duplicati/Library/Snapshots/WindowsSnapshot.cs b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
index f2d35742d..d37520aae 100644
--- a/Duplicati/Library/Snapshots/WindowsSnapshot.cs
+++ b/Duplicati/Library/Snapshots/WindowsSnapshot.cs
@@ -105,7 +105,7 @@ namespace Duplicati.Library.Snapshots
m_sourcepaths = new string[sourcepaths.Length];
for(int i = 0; i < m_sourcepaths.Length; i++)
- m_sourcepaths[i] = Utility.Utility.AppendDirSeparator(sourcepaths[i]);
+ m_sourcepaths[i] = System.IO.Directory.Exists(sourcepaths[i]) ? Utility.Utility.AppendDirSeparator(sourcepaths[i]) : sourcepaths[i];
try
{
diff --git a/Duplicati/Library/Utility/Utility.cs b/Duplicati/Library/Utility/Utility.cs
index a48e2a262..eb678985c 100644
--- a/Duplicati/Library/Utility/Utility.cs
+++ b/Duplicati/Library/Utility/Utility.cs
@@ -215,7 +215,7 @@ namespace Duplicati.Library.Utility
/// </summary>
/// <param name="path">The path to return data from</param>
/// <returns>Attributes for the file or folder</returns>
- public delegate System.IO.FileAttributes ExtractFileAttributes(string path);
+ public delegate System.IO.FileAttributes ExtractFileAttributes(string path);
/// <summary>
/// Returns a list of all files found in the given folder.
/// The search is recursive.
@@ -224,10 +224,10 @@ namespace Duplicati.Library.Utility
/// <param name="filter">An optional filter to apply to the filenames</param>
/// <param name="callback">The function to call with the filenames</param>
/// <returns>A list of the full filenames</returns>
- public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback)
- {
- return EnumerateFileSystemEntries(rootpath, callback, new FileSystemInteraction(System.IO.Directory.GetDirectories), new FileSystemInteraction(System.IO.Directory.GetFiles));
- }
+ public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback)
+ {
+ return EnumerateFileSystemEntries(rootpath, callback, new FileSystemInteraction(System.IO.Directory.GetDirectories), new FileSystemInteraction(System.IO.Directory.GetFiles));
+ }
/// <summary>
/// Returns a list of all files found in the given folder.
/// The search is recursive.
@@ -237,10 +237,10 @@ namespace Duplicati.Library.Utility
/// <param name="folderList">A function to call that lists all folders in the supplied folder</param>
/// <param name="fileList">A function to call that lists all files in the supplied folder</param>
/// <returns>A list of the full filenames</returns>
- public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback, FileSystemInteraction folderList, FileSystemInteraction fileList)
- {
- return EnumerateFileSystemEntries(rootpath, callback, folderList, fileList, null);
- }
+ public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback, FileSystemInteraction folderList, FileSystemInteraction fileList)
+ {
+ return EnumerateFileSystemEntries(rootpath, callback, folderList, fileList, null);
+ }
/// <summary>
/// Returns a list of all files found in the given folder.
/// The search is recursive.
@@ -251,77 +251,96 @@ namespace Duplicati.Library.Utility
/// <param name="fileList">A function to call that lists all files in the supplied folder</param>
/// <param name="attributeReader">A function to call that obtains the attributes for an element, set to null to avoid reading attributes</param>
/// <returns>A list of the full filenames</returns>
- public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback, FileSystemInteraction folderList, FileSystemInteraction fileList, ExtractFileAttributes attributeReader)
- {
- if (System.IO.Directory.Exists(rootpath))
- {
- Queue<string> lst = new Queue<string>();
- lst.Enqueue(rootpath);
+ public static IEnumerable<string> EnumerateFileSystemEntries(string rootpath, EnumerationFilterDelegate callback, FileSystemInteraction folderList, FileSystemInteraction fileList, ExtractFileAttributes attributeReader)
+ {
+ if (System.IO.Directory.Exists(rootpath))
+ {
+ Queue<string> lst = new Queue<string>();
+ lst.Enqueue(rootpath);
- while (lst.Count > 0)
- {
- string f = AppendDirSeparator(lst.Dequeue());
- string fv = null;
- try
- {
- System.IO.FileAttributes attr = attributeReader == null ? System.IO.FileAttributes.Directory : attributeReader(f);
- if (!callback(rootpath, f, attr))
- continue;
-
- fv = f;
-
- foreach(string s in folderList(f))
- lst.Enqueue(s);
- }
- catch (System.Threading.ThreadAbortException)
- {
- throw;
- }
- catch (Exception)
- {
- callback(rootpath, f, ATTRIBUTE_ERROR | System.IO.FileAttributes.Directory);
- }
+ while (lst.Count > 0)
+ {
+ string f = AppendDirSeparator(lst.Dequeue());
+ string fv = null;
+ try
+ {
+ System.IO.FileAttributes attr = attributeReader == null ? System.IO.FileAttributes.Directory : attributeReader(f);
+ if (!callback(rootpath, f, attr))
+ continue;
+
+ fv = f;
- if (fv != null)
- yield return fv;
+ foreach(string s in folderList(f))
+ lst.Enqueue(s);
+ }
+ catch (System.Threading.ThreadAbortException)
+ {
+ throw;
+ }
+ catch (Exception)
+ {
+ callback(rootpath, f, ATTRIBUTE_ERROR | System.IO.FileAttributes.Directory);
+ }
+
+ if (fv != null)
+ yield return fv;
+
+ string[] files = null;
+ if (fileList != null)
+ try
+ {
+ files = fileList(f);
+ }
+ catch (System.Threading.ThreadAbortException)
+ {
+ throw;
+ }
+ catch (Exception)
+ {
+ callback(rootpath, f, ATTRIBUTE_ERROR);
+ }
- string[] files = null;
- if (fileList != null)
- try
- {
- files = fileList(f);
- }
- catch (System.Threading.ThreadAbortException)
- {
- throw;
- }
- catch (Exception)
- {
- callback(rootpath, f, ATTRIBUTE_ERROR);
- }
-
- if (files != null)
- foreach(var s in files)
- {
- try
- {
- System.IO.FileAttributes attr = attributeReader == null ? System.IO.FileAttributes.Normal : attributeReader(s);
- if (!callback(rootpath, s, attr))
- continue;
- }
- catch (System.Threading.ThreadAbortException)
- {
- throw;
- }
- catch (Exception)
- {
- callback(rootpath, s, ATTRIBUTE_ERROR);
- continue;
- }
- yield return s;
- }
- }
- }
+ if (files != null)
+ foreach(var s in files)
+ {
+ try
+ {
+ System.IO.FileAttributes attr = attributeReader == null ? System.IO.FileAttributes.Normal : attributeReader(s);
+ if (!callback(rootpath, s, attr))
+ continue;
+ }
+ catch (System.Threading.ThreadAbortException)
+ {
+ throw;
+ }
+ catch (Exception)
+ {
+ callback(rootpath, s, ATTRIBUTE_ERROR);
+ continue;
+ }
+ yield return s;
+ }
+ }
+ }
+ else if (System.IO.File.Exists(rootpath))
+ {
+ try
+ {
+ System.IO.FileAttributes attr = attributeReader == null ? System.IO.FileAttributes.Normal : attributeReader(rootpath);
+ if (!callback(rootpath, rootpath, attr))
+ yield break;
+ }
+ catch (System.Threading.ThreadAbortException)
+ {
+ throw;
+ }
+ catch (Exception)
+ {
+ callback(rootpath, rootpath, ATTRIBUTE_ERROR);
+ yield break;
+ }
+ yield return rootpath;
+ }
}
/// <summary>
/// Calculates the size of files in a given folder