2023-09-26 08:57:27 -04:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2023-07-30 16:15:52 -04:00
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Text.RegularExpressions;
|
2023-05-14 22:35:06 -04:00
|
|
|
|
using Serilog;
|
2023-05-11 23:11:39 -04:00
|
|
|
|
using SPTInstaller.Models;
|
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
namespace SPTInstaller.Helpers;
|
|
|
|
|
|
|
|
|
|
public static class FileHelper
|
2023-05-11 23:11:39 -04:00
|
|
|
|
{
|
2023-09-16 16:10:40 -04:00
|
|
|
|
private static Result IterateDirectories(DirectoryInfo sourceDir, DirectoryInfo targetDir, string[] exclusions)
|
2023-05-11 23:11:39 -04:00
|
|
|
|
{
|
2023-07-12 09:19:33 +02:00
|
|
|
|
try
|
2023-05-11 23:11:39 -04:00
|
|
|
|
{
|
2023-07-12 09:19:33 +02:00
|
|
|
|
foreach (var dir in sourceDir.GetDirectories("*", SearchOption.AllDirectories))
|
2023-05-11 23:11:39 -04:00
|
|
|
|
{
|
2023-09-16 18:12:24 -04:00
|
|
|
|
var exclude = false;
|
|
|
|
|
|
|
|
|
|
foreach (var exclusion in exclusions)
|
2023-09-16 16:10:40 -04:00
|
|
|
|
{
|
2023-09-16 18:12:24 -04:00
|
|
|
|
var currentDirRelativePath = dir.FullName.Replace(sourceDir.FullName, "");
|
|
|
|
|
|
|
|
|
|
if (currentDirRelativePath.StartsWith(exclusion) || currentDirRelativePath == exclusion)
|
|
|
|
|
{
|
|
|
|
|
exclude = true;
|
2024-02-06 18:59:39 -05:00
|
|
|
|
Log.Debug($"EXCLUSION FOUND :: DIR\nExclusion: '{exclusion}'\nPath: '{currentDirRelativePath}'");
|
2023-09-16 18:12:24 -04:00
|
|
|
|
break;
|
|
|
|
|
}
|
2023-09-16 16:10:40 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-16 18:12:24 -04:00
|
|
|
|
if (exclude)
|
|
|
|
|
continue;
|
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
Directory.CreateDirectory(dir.FullName.Replace(sourceDir.FullName, targetDir.FullName));
|
2023-05-11 23:11:39 -04:00
|
|
|
|
}
|
2023-07-12 09:19:33 +02:00
|
|
|
|
return Result.FromSuccess();
|
2023-05-11 23:11:39 -04:00
|
|
|
|
}
|
2023-09-16 16:10:40 -04:00
|
|
|
|
catch (Exception ex)
|
2023-05-11 23:11:39 -04:00
|
|
|
|
{
|
2023-07-12 09:19:33 +02:00
|
|
|
|
Log.Error(ex, "Error while creating directories");
|
|
|
|
|
return Result.FromError(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-11 23:11:39 -04:00
|
|
|
|
|
2023-09-16 16:10:40 -04:00
|
|
|
|
private static Result IterateFiles(DirectoryInfo sourceDir, DirectoryInfo targetDir, string[] exclusions, Action<string, int> updateCallback = null)
|
2023-07-12 09:19:33 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int totalFiles = sourceDir.GetFiles("*.*", SearchOption.AllDirectories).Length;
|
|
|
|
|
int processedFiles = 0;
|
2023-05-11 23:11:39 -04:00
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
foreach (var file in sourceDir.GetFiles("*.*", SearchOption.AllDirectories))
|
2023-05-11 23:11:39 -04:00
|
|
|
|
{
|
2023-09-16 18:12:24 -04:00
|
|
|
|
var exclude = false;
|
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
updateCallback?.Invoke(file.Name, (int)Math.Floor(((double)processedFiles / totalFiles) * 100));
|
|
|
|
|
|
2023-09-16 16:10:40 -04:00
|
|
|
|
foreach (var exclusion in exclusions)
|
|
|
|
|
{
|
|
|
|
|
var currentFileRelativePath = file.FullName.Replace(sourceDir.FullName, "");
|
|
|
|
|
|
|
|
|
|
if (currentFileRelativePath.StartsWith(exclusion) || currentFileRelativePath == exclusion)
|
|
|
|
|
{
|
2023-09-16 18:12:24 -04:00
|
|
|
|
exclude = true;
|
2024-02-06 18:59:39 -05:00
|
|
|
|
Log.Debug($"EXCLUSION FOUND :: FILE\nExclusion: '{exclusion}'\nPath: '{currentFileRelativePath}'");
|
2023-09-16 18:12:24 -04:00
|
|
|
|
break;
|
2023-09-16 16:10:40 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-16 18:12:24 -04:00
|
|
|
|
if (exclude)
|
|
|
|
|
continue;
|
|
|
|
|
|
2024-02-06 18:59:39 -05:00
|
|
|
|
|
|
|
|
|
var targetFile = file.FullName.Replace(sourceDir.FullName, targetDir.FullName);
|
|
|
|
|
|
|
|
|
|
Log.Debug($"COPY\nSourceDir: '{sourceDir.FullName}'\nTargetDir: '{targetDir.FullName}'\nNewPath: '{targetFile}'");
|
|
|
|
|
|
|
|
|
|
File.Copy(file.FullName, targetFile, true);
|
2023-07-12 09:19:33 +02:00
|
|
|
|
processedFiles++;
|
2023-05-11 23:11:39 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
return Result.FromSuccess();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
2023-05-22 15:09:00 -04:00
|
|
|
|
{
|
2023-07-12 09:19:33 +02:00
|
|
|
|
Log.Error(ex, "Error while copying files");
|
|
|
|
|
return Result.FromError(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-22 15:09:00 -04:00
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
public static string GetRedactedPath(string path)
|
|
|
|
|
{
|
|
|
|
|
var nameMatched = Regex.Match(path, @".:\\[uU]sers\\(?<NAME>[^\\]+)");
|
2023-05-22 15:09:00 -04:00
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
if (nameMatched.Success)
|
|
|
|
|
{
|
|
|
|
|
var name = nameMatched.Groups["NAME"].Value;
|
|
|
|
|
return path.Replace(name, "-REDACTED-");
|
2023-05-22 15:09:00 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-16 16:10:40 -04:00
|
|
|
|
public static Result CopyDirectoryWithProgress(DirectoryInfo sourceDir, DirectoryInfo targetDir, IProgress<double> progress = null, string[] exclusions = null) =>
|
|
|
|
|
CopyDirectoryWithProgress(sourceDir, targetDir, (msg, prog) => progress?.Report(prog), exclusions);
|
2023-05-11 23:11:39 -04:00
|
|
|
|
|
2023-09-16 16:10:40 -04:00
|
|
|
|
public static Result CopyDirectoryWithProgress(DirectoryInfo sourceDir, DirectoryInfo targetDir, Action<string, int> updateCallback = null, string[] exclusions = null)
|
2023-07-12 09:19:33 +02:00
|
|
|
|
{
|
|
|
|
|
try
|
2023-05-11 23:11:39 -04:00
|
|
|
|
{
|
2023-09-16 16:10:40 -04:00
|
|
|
|
var iterateDirectoriesResult = IterateDirectories(sourceDir, targetDir, exclusions ??= new string[0]);
|
2023-05-11 23:11:39 -04:00
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
if(!iterateDirectoriesResult.Succeeded) return iterateDirectoriesResult;
|
2023-05-11 23:11:39 -04:00
|
|
|
|
|
2023-09-16 16:10:40 -04:00
|
|
|
|
var iterateFilesResult = IterateFiles(sourceDir, targetDir, exclusions ??= new string[0], updateCallback);
|
2023-05-11 23:11:39 -04:00
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
if (!iterateFilesResult.Succeeded) return iterateDirectoriesResult;
|
2023-05-11 23:11:39 -04:00
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
return Result.FromSuccess();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Error(ex, "Error during directory copy");
|
|
|
|
|
return Result.FromError(ex.Message);
|
2023-05-11 23:11:39 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-07-30 16:15:52 -04:00
|
|
|
|
|
2024-03-23 14:15:48 -04:00
|
|
|
|
public static bool StreamAssemblyResourceOut(string resourceName, string outputFilePath)
|
2023-07-30 16:15:52 -04:00
|
|
|
|
{
|
2024-03-23 14:15:48 -04:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var assembly = Assembly.GetExecutingAssembly();
|
2023-07-30 16:15:52 -04:00
|
|
|
|
|
2024-03-23 14:15:48 -04:00
|
|
|
|
FileInfo outputFile = new FileInfo(outputFilePath);
|
2023-07-30 16:15:52 -04:00
|
|
|
|
|
2024-03-23 14:15:48 -04:00
|
|
|
|
if (outputFile.Exists)
|
|
|
|
|
{
|
|
|
|
|
outputFile.Delete();
|
|
|
|
|
}
|
2023-07-30 16:15:52 -04:00
|
|
|
|
|
2024-03-23 14:15:48 -04:00
|
|
|
|
if (!outputFile.Directory.Exists)
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(outputFile.Directory.FullName);
|
|
|
|
|
}
|
2023-07-30 16:15:52 -04:00
|
|
|
|
|
2024-03-23 14:15:48 -04:00
|
|
|
|
var resName = assembly.GetManifestResourceNames().First(x => x.EndsWith(resourceName));
|
2023-07-30 16:15:52 -04:00
|
|
|
|
|
2024-03-23 14:15:48 -04:00
|
|
|
|
using (FileStream fs = File.Create(outputFilePath))
|
|
|
|
|
using (Stream s = assembly.GetManifestResourceStream(resName))
|
|
|
|
|
{
|
|
|
|
|
s.CopyTo(fs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
outputFile.Refresh();
|
|
|
|
|
return outputFile.Exists;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
2023-07-30 16:15:52 -04:00
|
|
|
|
{
|
2024-03-23 14:15:48 -04:00
|
|
|
|
Log.Fatal(ex, $"Failed to stream resource out: {resourceName}");
|
|
|
|
|
return false;
|
2023-07-30 16:15:52 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 08:57:27 -04:00
|
|
|
|
private enum PathCheckType
|
2023-08-22 10:21:52 -04:00
|
|
|
|
{
|
2023-09-26 08:57:27 -04:00
|
|
|
|
EndsWith = 0,
|
|
|
|
|
Contains = 1,
|
2023-11-15 09:57:27 -05:00
|
|
|
|
DriveRoot = 2
|
2023-09-26 08:57:27 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool CheckPathForProblemLocations(string path, out string detectedName)
|
|
|
|
|
{
|
|
|
|
|
detectedName = "";
|
2023-08-22 10:21:52 -04:00
|
|
|
|
|
2023-09-26 08:57:27 -04:00
|
|
|
|
var problemNames = new Dictionary<string, PathCheckType>()
|
|
|
|
|
{
|
2024-03-25 21:02:26 +00:00
|
|
|
|
{ "Desktop", PathCheckType.EndsWith },
|
2024-03-25 18:27:57 -04:00
|
|
|
|
{ "Documents", PathCheckType.EndsWith },
|
|
|
|
|
{ "scoped_dir", PathCheckType.Contains },
|
|
|
|
|
{ "Downloads", PathCheckType.Contains },
|
2023-09-26 08:57:27 -04:00
|
|
|
|
{ "OneDrive", PathCheckType.Contains },
|
|
|
|
|
{ "NextCloud", PathCheckType.Contains },
|
|
|
|
|
{ "DropBox", PathCheckType.Contains },
|
|
|
|
|
{ "Google", PathCheckType.Contains },
|
2024-03-25 18:27:57 -04:00
|
|
|
|
{ "Program Files", PathCheckType.Contains },
|
|
|
|
|
{ "Program Files (x86)", PathCheckType.Contains },
|
|
|
|
|
{ "Drive Root", PathCheckType.DriveRoot }
|
2023-09-26 08:57:27 -04:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach (var name in problemNames)
|
|
|
|
|
{
|
|
|
|
|
switch (name.Value)
|
|
|
|
|
{
|
|
|
|
|
case PathCheckType.EndsWith:
|
|
|
|
|
if (path.ToLower().EndsWith(name.Key.ToLower()))
|
|
|
|
|
{
|
|
|
|
|
detectedName = name.Key;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PathCheckType.Contains:
|
|
|
|
|
if (path.ToLower().Contains(name.Key.ToLower()))
|
|
|
|
|
{
|
|
|
|
|
detectedName = name.Key;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-11-15 09:57:27 -05:00
|
|
|
|
case PathCheckType.DriveRoot:
|
|
|
|
|
if (Regex.Match(path.ToLower(), @"^\w:(\\|\/)$").Success)
|
|
|
|
|
{
|
|
|
|
|
detectedName = name.Key;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2023-09-26 08:57:27 -04:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-22 10:21:52 -04:00
|
|
|
|
|
2023-09-26 08:57:27 -04:00
|
|
|
|
return false;
|
2023-08-22 10:21:52 -04:00
|
|
|
|
}
|
|
|
|
|
|
2023-07-12 09:19:33 +02:00
|
|
|
|
}
|