2020-04-29 08:58:52 +00:00
|
|
|
|
using System;
|
2020-04-08 06:14:28 +00:00
|
|
|
|
using System.Diagnostics;
|
2020-02-25 10:08:51 +00:00
|
|
|
|
using System.IO;
|
2024-05-16 11:22:08 +00:00
|
|
|
|
using System.Linq;
|
2023-01-22 04:59:32 +00:00
|
|
|
|
#pragma warning disable IDE0005
|
2023-01-19 15:26:10 +00:00
|
|
|
|
using System.Windows;
|
2023-01-22 04:59:32 +00:00
|
|
|
|
#pragma warning restore IDE0005
|
2020-02-25 10:08:51 +00:00
|
|
|
|
|
2020-04-21 09:12:17 +00:00
|
|
|
|
namespace Flow.Launcher.Plugin.SharedCommands
|
2020-02-25 10:08:51 +00:00
|
|
|
|
{
|
2022-08-09 00:35:38 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Commands that are useful to run on files... and folders!
|
|
|
|
|
|
/// </summary>
|
2020-02-25 10:08:51 +00:00
|
|
|
|
public static class FilesFolders
|
|
|
|
|
|
{
|
2020-04-23 11:56:11 +00:00
|
|
|
|
private const string FileExplorerProgramName = "explorer";
|
2020-06-29 22:15:10 +00:00
|
|
|
|
|
2020-07-21 22:19:35 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Copies the folder and all of its files and folders
|
|
|
|
|
|
/// including subfolders to the target location
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="sourcePath"></param>
|
|
|
|
|
|
/// <param name="targetPath"></param>
|
2024-11-25 02:38:43 +00:00
|
|
|
|
/// <param name="messageBoxExShow"></param>
|
2024-12-01 10:38:48 +00:00
|
|
|
|
public static void CopyAll(this string sourcePath, string targetPath, Func<string, MessageBoxResult> messageBoxExShow = null)
|
2020-02-25 10:08:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
// Get the subdirectories for the specified directory.
|
|
|
|
|
|
DirectoryInfo dir = new DirectoryInfo(sourcePath);
|
|
|
|
|
|
|
|
|
|
|
|
if (!dir.Exists)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new DirectoryNotFoundException(
|
|
|
|
|
|
"Source directory does not exist or could not be found: "
|
|
|
|
|
|
+ sourcePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
DirectoryInfo[] dirs = dir.GetDirectories();
|
|
|
|
|
|
// If the destination directory doesn't exist, create it.
|
|
|
|
|
|
if (!Directory.Exists(targetPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
Directory.CreateDirectory(targetPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get the files in the directory and copy them to the new location.
|
|
|
|
|
|
FileInfo[] files = dir.GetFiles();
|
|
|
|
|
|
foreach (FileInfo file in files)
|
|
|
|
|
|
{
|
|
|
|
|
|
string temppath = Path.Combine(targetPath, file.Name);
|
|
|
|
|
|
file.CopyTo(temppath, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Recursively copy subdirectories by calling itself on each subdirectory until there are no more to copy
|
|
|
|
|
|
foreach (DirectoryInfo subdir in dirs)
|
|
|
|
|
|
{
|
|
|
|
|
|
string temppath = Path.Combine(targetPath, subdir.Name);
|
2024-11-25 02:38:43 +00:00
|
|
|
|
CopyAll(subdir.FullName, temppath, messageBoxExShow);
|
2020-02-25 10:08:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-08-08 04:31:38 +00:00
|
|
|
|
catch (Exception)
|
2020-02-25 10:08:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
2022-08-08 04:31:38 +00:00
|
|
|
|
throw;
|
2020-02-25 10:08:51 +00:00
|
|
|
|
#else
|
2024-12-01 10:38:48 +00:00
|
|
|
|
messageBoxExShow ??= MessageBox.Show;
|
2024-11-25 02:38:43 +00:00
|
|
|
|
messageBoxExShow(string.Format("Copying path {0} has failed, it will now be deleted for consistency", targetPath));
|
2024-11-26 11:28:39 +00:00
|
|
|
|
RemoveFolderIfExists(targetPath, messageBoxExShow);
|
2020-02-25 10:08:51 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-09 00:35:38 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Check if the files and directories are identical between <paramref name="fromPath"/>
|
|
|
|
|
|
/// and <paramref name="toPath"/>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="fromPath"></param>
|
|
|
|
|
|
/// <param name="toPath"></param>
|
2024-11-25 02:38:43 +00:00
|
|
|
|
/// <param name="messageBoxExShow"></param>
|
2022-08-09 00:35:38 +00:00
|
|
|
|
/// <returns></returns>
|
2024-12-01 10:38:48 +00:00
|
|
|
|
public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPath, Func<string, MessageBoxResult> messageBoxExShow = null)
|
2020-02-25 10:08:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var fromDir = new DirectoryInfo(fromPath);
|
|
|
|
|
|
var toDir = new DirectoryInfo(toPath);
|
|
|
|
|
|
|
|
|
|
|
|
if (fromDir.GetFiles("*", SearchOption.AllDirectories).Length != toDir.GetFiles("*", SearchOption.AllDirectories).Length)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
if (fromDir.GetDirectories("*", SearchOption.AllDirectories).Length != toDir.GetDirectories("*", SearchOption.AllDirectories).Length)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2022-08-08 04:31:38 +00:00
|
|
|
|
catch (Exception)
|
2020-02-25 10:08:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
2022-08-08 04:31:38 +00:00
|
|
|
|
throw;
|
2020-02-25 10:08:51 +00:00
|
|
|
|
#else
|
2024-12-01 10:38:48 +00:00
|
|
|
|
messageBoxExShow ??= MessageBox.Show;
|
2024-11-25 02:38:43 +00:00
|
|
|
|
messageBoxExShow(string.Format("Unable to verify folders and files between {0} and {1}", fromPath, toPath));
|
2020-02-25 10:08:51 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-09 00:35:38 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Deletes a folder if it exists
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="path"></param>
|
2024-11-25 02:38:43 +00:00
|
|
|
|
/// <param name="messageBoxExShow"></param>
|
2024-12-01 10:38:48 +00:00
|
|
|
|
public static void RemoveFolderIfExists(this string path, Func<string, MessageBoxResult> messageBoxExShow = null)
|
2020-02-25 10:08:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (Directory.Exists(path))
|
|
|
|
|
|
Directory.Delete(path, true);
|
|
|
|
|
|
}
|
2022-08-08 04:31:38 +00:00
|
|
|
|
catch (Exception)
|
2020-02-25 10:08:51 +00:00
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
2022-08-08 04:31:38 +00:00
|
|
|
|
throw;
|
2020-02-25 10:08:51 +00:00
|
|
|
|
#else
|
2024-12-01 10:38:48 +00:00
|
|
|
|
messageBoxExShow ??= MessageBox.Show;
|
2024-11-25 02:38:43 +00:00
|
|
|
|
messageBoxExShow(string.Format("Not able to delete folder {0}, please go to the location and manually delete it", path));
|
2020-02-25 10:08:51 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-03-05 12:10:16 +00:00
|
|
|
|
|
2022-08-09 00:35:38 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Checks if a directory exists
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="path"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2020-03-05 12:10:16 +00:00
|
|
|
|
public static bool LocationExists(this string path)
|
|
|
|
|
|
{
|
|
|
|
|
|
return Directory.Exists(path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-09 00:35:38 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Checks if a file exists
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="filePath"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2020-09-21 22:56:41 +00:00
|
|
|
|
public static bool FileExists(this string filePath)
|
2020-03-05 12:10:16 +00:00
|
|
|
|
{
|
|
|
|
|
|
return File.Exists(filePath);
|
|
|
|
|
|
}
|
2020-04-08 06:14:28 +00:00
|
|
|
|
|
2022-08-09 00:35:38 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Open a directory window (using the OS's default handler, usually explorer)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="fileOrFolderPath"></param>
|
2024-11-25 02:38:43 +00:00
|
|
|
|
/// <param name="messageBoxExShow"></param>
|
2024-12-01 10:38:48 +00:00
|
|
|
|
public static void OpenPath(string fileOrFolderPath, Func<string, MessageBoxResult> messageBoxExShow = null)
|
2020-04-08 06:14:28 +00:00
|
|
|
|
{
|
2023-03-03 12:12:44 +00:00
|
|
|
|
var psi = new ProcessStartInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
FileName = FileExplorerProgramName,
|
|
|
|
|
|
UseShellExecute = true,
|
|
|
|
|
|
Arguments = '"' + fileOrFolderPath + '"'
|
|
|
|
|
|
};
|
2020-04-08 06:14:28 +00:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2020-09-21 22:56:41 +00:00
|
|
|
|
if (LocationExists(fileOrFolderPath) || FileExists(fileOrFolderPath))
|
2020-04-23 21:59:24 +00:00
|
|
|
|
Process.Start(psi);
|
2020-04-08 06:14:28 +00:00
|
|
|
|
}
|
2022-08-08 04:31:38 +00:00
|
|
|
|
catch (Exception)
|
2020-04-08 06:14:28 +00:00
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
2022-08-08 04:31:38 +00:00
|
|
|
|
throw;
|
2020-04-08 06:14:28 +00:00
|
|
|
|
#else
|
2024-12-01 10:38:48 +00:00
|
|
|
|
messageBoxExShow ??= MessageBox.Show;
|
2024-11-25 02:38:43 +00:00
|
|
|
|
messageBoxExShow(string.Format("Unable to open the path {0}, please check if it exists", fileOrFolderPath));
|
2020-04-08 06:14:28 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-24 09:18:58 +00:00
|
|
|
|
|
2023-03-24 07:22:29 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Open a file with associated application
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="filePath">File path</param>
|
|
|
|
|
|
/// <param name="workingDir">Working directory</param>
|
|
|
|
|
|
/// <param name="asAdmin">Open as Administrator</param>
|
2024-12-01 10:38:48 +00:00
|
|
|
|
/// <param name="messageBoxExShow"></param>
|
|
|
|
|
|
public static void OpenFile(string filePath, string workingDir = "", bool asAdmin = false, Func<string, MessageBoxResult> messageBoxExShow = null)
|
2023-03-24 07:22:29 +00:00
|
|
|
|
{
|
|
|
|
|
|
var psi = new ProcessStartInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
FileName = filePath,
|
|
|
|
|
|
UseShellExecute = true,
|
|
|
|
|
|
WorkingDirectory = workingDir,
|
|
|
|
|
|
Verb = asAdmin ? "runas" : string.Empty
|
|
|
|
|
|
};
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (FileExists(filePath))
|
|
|
|
|
|
Process.Start(psi);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
throw;
|
|
|
|
|
|
#else
|
2024-12-01 10:38:48 +00:00
|
|
|
|
messageBoxExShow ??= MessageBox.Show;
|
2024-11-25 02:38:43 +00:00
|
|
|
|
messageBoxExShow(string.Format("Unable to open the path {0}, please check if it exists", filePath));
|
2023-03-24 07:22:29 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-16 11:22:08 +00:00
|
|
|
|
///<summary>
|
|
|
|
|
|
/// This checks whether a given string is a zip file path.
|
|
|
|
|
|
/// By default does not check if the zip file actually exist on disk, can do so by
|
|
|
|
|
|
/// setting checkFileExists = true.
|
|
|
|
|
|
///</summary>
|
|
|
|
|
|
public static bool IsZipFilePath(string querySearchString, bool checkFileExists = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsLocationPathString(querySearchString) && querySearchString.Split('.').Last() == "zip")
|
|
|
|
|
|
{
|
|
|
|
|
|
if (checkFileExists)
|
|
|
|
|
|
return FileExists(querySearchString);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-24 09:18:58 +00:00
|
|
|
|
///<summary>
|
|
|
|
|
|
/// This checks whether a given string is a directory path or network location string.
|
|
|
|
|
|
/// It does not check if location actually exists.
|
|
|
|
|
|
///</summary>
|
2021-01-22 08:22:52 +00:00
|
|
|
|
public static bool IsLocationPathString(this string querySearchString)
|
2020-05-24 09:18:58 +00:00
|
|
|
|
{
|
2021-01-22 08:19:03 +00:00
|
|
|
|
if (string.IsNullOrEmpty(querySearchString) || querySearchString.Length < 3)
|
2020-05-24 09:18:58 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
// // shared folder location, and not \\\location\
|
2021-01-22 08:19:03 +00:00
|
|
|
|
if (querySearchString.StartsWith(@"\\")
|
|
|
|
|
|
&& querySearchString[2] != '\\')
|
2020-05-24 09:18:58 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
// c:\
|
2021-01-22 08:19:03 +00:00
|
|
|
|
if (char.IsLetter(querySearchString[0])
|
2020-05-24 09:18:58 +00:00
|
|
|
|
&& querySearchString[1] == ':'
|
|
|
|
|
|
&& querySearchString[2] == '\\')
|
2021-01-22 08:19:03 +00:00
|
|
|
|
{
|
|
|
|
|
|
return querySearchString.Length == 3 || querySearchString[3] != '\\';
|
|
|
|
|
|
}
|
2020-05-24 09:18:58 +00:00
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2020-05-26 10:18:18 +00:00
|
|
|
|
|
|
|
|
|
|
///<summary>
|
|
|
|
|
|
/// Gets the previous level directory from a path string.
|
|
|
|
|
|
/// Checks that previous level directory exists and returns it
|
2020-07-22 10:41:50 +00:00
|
|
|
|
/// as a path string, or empty string if doesn't exist
|
2020-05-26 10:18:18 +00:00
|
|
|
|
///</summary>
|
|
|
|
|
|
public static string GetPreviousExistingDirectory(Func<string, bool> locationExists, string path)
|
|
|
|
|
|
{
|
2020-05-26 11:47:47 +00:00
|
|
|
|
var index = path.LastIndexOf('\\');
|
2020-05-26 10:18:18 +00:00
|
|
|
|
if (index > 0 && index < (path.Length - 1))
|
|
|
|
|
|
{
|
2025-04-11 14:16:04 +00:00
|
|
|
|
string previousDirectoryPath = path[..(index + 1)];
|
|
|
|
|
|
return locationExists(previousDirectoryPath) ? previousDirectoryPath : string.Empty;
|
2020-05-26 10:18:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-04-11 14:16:04 +00:00
|
|
|
|
return string.Empty;
|
2020-05-26 10:18:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-28 11:33:18 +00:00
|
|
|
|
|
|
|
|
|
|
///<summary>
|
2020-06-06 12:13:22 +00:00
|
|
|
|
/// Returns the previous level directory if path incomplete (does not end with '\').
|
2020-06-02 10:21:28 +00:00
|
|
|
|
/// Does not check if previous level directory exists.
|
|
|
|
|
|
/// Returns passed in string if is complete path
|
2020-05-28 11:33:18 +00:00
|
|
|
|
///</summary>
|
2020-06-02 10:21:28 +00:00
|
|
|
|
public static string ReturnPreviousDirectoryIfIncompleteString(string path)
|
2020-05-28 11:33:18 +00:00
|
|
|
|
{
|
|
|
|
|
|
if (!path.EndsWith("\\"))
|
|
|
|
|
|
{
|
|
|
|
|
|
// not full path, get previous level directory string
|
|
|
|
|
|
var indexOfSeparator = path.LastIndexOf('\\');
|
|
|
|
|
|
|
2025-04-11 14:16:04 +00:00
|
|
|
|
return path[..(indexOfSeparator + 1)];
|
2020-05-28 11:33:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return path;
|
|
|
|
|
|
}
|
2023-01-19 12:29:25 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2023-09-08 17:49:18 +00:00
|
|
|
|
/// Returns if <paramref name="parentPath"/> contains <paramref name="subPath"/>. Equal paths are not considered to be contained by default.
|
2023-01-19 12:29:25 +00:00
|
|
|
|
/// From https://stackoverflow.com/a/66877016
|
|
|
|
|
|
/// </summary>
|
2023-01-19 13:33:09 +00:00
|
|
|
|
/// <param name="parentPath">Parent path</param>
|
|
|
|
|
|
/// <param name="subPath">Sub path</param>
|
|
|
|
|
|
/// <param name="allowEqual">If <see langword="true"/>, when <paramref name="parentPath"/> and <paramref name="subPath"/> are equal, returns <see langword="true"/></param>
|
2023-01-19 12:29:25 +00:00
|
|
|
|
/// <returns></returns>
|
2023-01-19 13:33:09 +00:00
|
|
|
|
public static bool PathContains(string parentPath, string subPath, bool allowEqual = false)
|
2023-01-19 12:29:25 +00:00
|
|
|
|
{
|
2023-01-20 07:36:14 +00:00
|
|
|
|
var rel = Path.GetRelativePath(parentPath.EnsureTrailingSlash(), subPath);
|
2023-01-19 13:33:09 +00:00
|
|
|
|
return (rel != "." || allowEqual)
|
2023-01-19 12:29:25 +00:00
|
|
|
|
&& rel != ".."
|
|
|
|
|
|
&& !rel.StartsWith("../")
|
|
|
|
|
|
&& !rel.StartsWith(@"..\")
|
|
|
|
|
|
&& !Path.IsPathRooted(rel);
|
|
|
|
|
|
}
|
2023-01-20 06:27:12 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns path ended with "\"
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="path"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static string EnsureTrailingSlash(this string path)
|
|
|
|
|
|
{
|
|
|
|
|
|
return path.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;
|
|
|
|
|
|
}
|
2025-04-02 12:17:32 +00:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Validates a directory, creating it if it doesn't exist
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="path"></param>
|
|
|
|
|
|
public static void ValidateDirectory(string path)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!Directory.Exists(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
Directory.CreateDirectory(path);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Validates a data directory, synchronizing it by ensuring all files from a bundled source directory exist in it.
|
|
|
|
|
|
/// If files are missing or outdated, they are copied from the bundled directory to the data directory.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="bundledDataDirectory"></param>
|
|
|
|
|
|
/// <param name="dataDirectory"></param>
|
|
|
|
|
|
public static void ValidateDataDirectory(string bundledDataDirectory, string dataDirectory)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!Directory.Exists(dataDirectory))
|
|
|
|
|
|
{
|
|
|
|
|
|
Directory.CreateDirectory(dataDirectory);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var bundledDataPath in Directory.GetFiles(bundledDataDirectory))
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = Path.GetFileName(bundledDataPath);
|
|
|
|
|
|
if (data == null) continue;
|
|
|
|
|
|
var dataPath = Path.Combine(dataDirectory, data);
|
|
|
|
|
|
if (!File.Exists(dataPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
File.Copy(bundledDataPath, dataPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var time1 = new FileInfo(bundledDataPath).LastWriteTimeUtc;
|
|
|
|
|
|
var time2 = new FileInfo(dataPath).LastWriteTimeUtc;
|
|
|
|
|
|
if (time1 != time2)
|
|
|
|
|
|
{
|
|
|
|
|
|
File.Copy(bundledDataPath, dataPath, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-02-25 10:08:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|