Added support for reading the list of folder/file exclusion from the Windows registry

This commit is contained in:
Kenneth Skovhede
2017-10-31 10:57:37 +01:00
parent f20ceab9e5
commit 2ff3fa6a8d
+64 -1
View File
@@ -178,7 +178,7 @@ namespace Duplicati.Library.Utility
/// <returns>Windows filters</returns>
private static string[] CreateWindowsFilters()
{
return new[]
var filters = new[]
{
DefaultFilters.CreateWildcardFilter(@"*.rbf"),
DefaultFilters.CreateWildcardFilter(@"*.tmp"),
@@ -233,6 +233,12 @@ namespace Duplicati.Library.Utility
DefaultFilters.CreateWildcardFilter(@"?:/Windows/Installer*"),
DefaultFilters.CreateWildcardFilter(@"?:/Windows/Temp*"),
};
var extra = GetWindowsRegistryFilters();
if (extra == null || extra.Length == 0)
return filters;
return filters.Union(extra).ToArray();
}
/// <summary>
@@ -368,5 +374,62 @@ namespace Duplicati.Library.Utility
string escaped = System.Text.RegularExpressions.Regex.Escape(System.IO.Path.DirectorySeparatorChar.ToString());
return "[" + filter.Replace(escapedAlt, escaped) + "]";
}
/// <summary>
/// Wrapper method for getting a list of exclude paths from the Windows registry.
/// This method guards the call to <see cref="GetWindowsRegistryFiltersInternal"/> to avoid loader errors.
/// </summary>
/// <returns>The list of paths to exclude.</returns>
private static string[] GetWindowsRegistryFilters()
{
try
{
return GetWindowsRegistryFiltersInternal();
}
catch
{
}
return new string[0];
}
/// <summary>
/// Helper method that reads the Windows registry and finds paths to exclude.
/// This method should not be called directly as that could cause loader errors on Mono.
/// </summary>
/// <returns>The list of paths to exclude.</returns>
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private static string[] GetWindowsRegistryFiltersInternal()
{
var rk = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Default);
if (rk == null)
return new string[0];
var sk = rk.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToBackup");
if (sk == null)
return new string[0];
// Each value in this key is a potential path
return sk.GetValueNames()
.Where(x => x != null)
.SelectMany(x =>
{
var v = sk.GetValue(x);
if (v is string)
return new string[] { (string)v };
else if (v is string[])
return (string[])v;
else
return new string[0];
})
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(x => Environment.ExpandEnvironmentVariables(x))
.Where(x => !string.IsNullOrWhiteSpace(x))
.Where(x => x.IndexOfAny(System.IO.Path.GetInvalidPathChars()) < 0)
.Where(x => System.IO.Path.IsPathRooted(x))
.Select(x => x.EndsWith(" /s", StringComparison.OrdinalIgnoreCase) ? x.Substring(0, x.Length - 3).TrimEnd() : x)
.ToArray();
}
}
}