From 11fe02659e41baaf767a4bc2e6470c64ffdd19c4 Mon Sep 17 00:00:00 2001 From: Plague <36628963+OFWModz@users.noreply.github.com> Date: Sun, 14 Mar 2021 03:00:44 +0000 Subject: [PATCH] Support Symbolic Links In Auto Delete & Clearing Buttons --- CacheDeleter.cs | 100 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 18 deletions(-) diff --git a/CacheDeleter.cs b/CacheDeleter.cs index 96c897f..88a07a6 100644 --- a/CacheDeleter.cs +++ b/CacheDeleter.cs @@ -1,7 +1,11 @@ +using Microsoft.Win32.SafeHandles; using System; +using System.ComponentModel; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Security.Principal; +using System.Text; using System.Windows.Forms; namespace VRChat_Cache_Auto_Deleter @@ -13,6 +17,9 @@ public CacheDeleter() InitializeComponent(); } + public long LastKnownDriveSpace = 120; + public long LastKnownCacheSize = 0; + private void checkBox1_CheckedChanged(object sender, EventArgs e) { if (checkBox1.Checked) @@ -39,12 +46,10 @@ public static bool IsAdministrator() /// public void ClearVRCCache() { - if (Directory.Exists(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\")) + if (Directory.Exists(VRChatCacheDir)) { foreach (var folder in Directory.GetDirectories( - Directory.GetParent( - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + - "\\LocalLow\\VRChat\\vrchat\\")) + VRChatCacheDir + "\\vrchat\\")) { var DirInfo = new DirectoryInfo(folder); @@ -114,7 +119,7 @@ private void AutoDeleteTimer_Tick(object sender, EventArgs e) if (Drive != null) { - if (Drive.AvailableSpaceInGB() == 5 || (Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\").GetDirectorySizeInGB() > 19) // Drive Space Is Less Than 5GB Or Cache Is Full + if (Drive.AvailableSpaceInGB() == 5 || VRChatCacheDir.GetDirectorySizeInGB() > 19) // Drive Space Is Less Than 5GB Or Cache Is Full { AutoDeleteTimer.Stop(); AutoDeleteTimer.Enabled = false; @@ -125,6 +130,9 @@ private void AutoDeleteTimer_Tick(object sender, EventArgs e) AutoDeleteTimer.Start(); } } + + label2.Text = + $"Last Known Free Drive Space: {Drive.AvailableSpaceInGB()}GB - Last Known Cache Size: {VRChatCacheDir.GetDirectorySizeInGB()}GB"; } private void button1_Click(object sender, EventArgs e) @@ -136,21 +144,21 @@ private void button1_Click(object sender, EventArgs e) Enabled = false; Directory.CreateDirectory(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\"); - if (Directory.Exists(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\")) + if (Directory.Exists(VRChatCacheDir)) { - CopyFolder(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\", Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\VRChat\\"); + CopyFolder(VRChatCacheDir, Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\VRChat\\"); } if (Directory.Exists(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\vrchat\\")) { - Directory.Delete(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\", true); + Directory.Delete(VRChatCacheDir, true); } System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal; startInfo.FileName = "cmd.exe"; - startInfo.Arguments = "/c mklink /d " + Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\" + " " + Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\VRChat\\"; + startInfo.Arguments = "/c mklink /d " + VRChatCacheDir + " " + Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\VRChat\\"; process.StartInfo = startInfo; process.Start(); @@ -173,12 +181,72 @@ private void button1_Click(object sender, EventArgs e) } } + public string VRChatCacheDir = + (Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + + "\\LocalLow\\VRChat"); + private void Form1_Load(object sender, EventArgs e) { foreach (DriveInfo drive in DriveInfo.GetDrives()) { comboBox2.Items.Add(drive.Name); } + + try + { + VRChatCacheDir = GetRealPath(VRChatCacheDir); + } + catch + { + VRChatCacheDir = + (Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + + "\\LocalLow\\VRChat"); + } + + if (!IsAdministrator()) + { + button1.Enabled = false; + button2.Enabled = false; + comboBox2.Enabled = false; + } + } + + [DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile); + + [DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int GetFinalPathNameByHandle([In] SafeFileHandle hFile, [Out] StringBuilder lpszFilePath, [In] int cchFilePath, [In] int dwFlags); + + private const int CREATION_DISPOSITION_OPEN_EXISTING = 3; + private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000; + + public static string GetRealPath(string path) + { + if (!Directory.Exists(path) && !File.Exists(path)) + { + throw new IOException("Path not found"); + } + + SafeFileHandle directoryHandle = CreateFile(path, 0, 2, IntPtr.Zero, CREATION_DISPOSITION_OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); //Handle file / folder + + if (directoryHandle.IsInvalid) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + StringBuilder result = new StringBuilder(512); + int mResult = GetFinalPathNameByHandle(directoryHandle, result, result.Capacity, 0); + + if (mResult < 0) + { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + + if (result.Length >= 4 && result[0] == '\\' && result[1] == '\\' && result[2] == '?' && result[3] == '\\') + { + return result.ToString().Substring(4); // "\\?\" remove + } + return result.ToString(); } public static void CopyFolder(string sourceFolder, string destFolder) @@ -206,7 +274,7 @@ public static void CopyFolder(string sourceFolder, string destFolder) private void button2_Click(object sender, EventArgs e) { - if (IsAdministrator() && Directory.Exists(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\") && comboBox2.Text.Contains(@":\")) + if (IsAdministrator() && Directory.Exists(VRChatCacheDir) && comboBox2.Text.Contains(@":\")) { Enabled = false; @@ -214,13 +282,13 @@ private void button2_Click(object sender, EventArgs e) System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal; startInfo.FileName = "cmd.exe"; - startInfo.Arguments = "/c rmdir " + Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\"; + startInfo.Arguments = "/c rmdir " + VRChatCacheDir; process.StartInfo = startInfo; process.Start(); if (Directory.Exists(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\VRChat\\")) { - CopyFolder(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\VRChat\\", Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) + "\\LocalLow\\VRChat\\"); + CopyFolder(Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).ToString().Replace(@"C:\", comboBox2.Text) + "\\LocalLow\\VRChat\\", VRChatCacheDir); } Enabled = true; @@ -289,15 +357,11 @@ public static long GetDirectorySize(this string Dir) } //Add size of files in the Current Directory to main size. - foreach (var fileInfo in Info.GetFiles()) + foreach (var fileInfo in Info.GetFiles("*.*", SearchOption.AllDirectories)) { - System.Threading.Interlocked.Add(ref startDirectorySize, fileInfo.Length); + startDirectorySize += fileInfo.Length; } - //Loop on Sub Direcotries in the Current Directory and Calculate it's files size. - System.Threading.Tasks.Parallel.ForEach(Info.GetDirectories(), (subDirectory) => - System.Threading.Interlocked.Add(ref startDirectorySize, GetDirectorySizeInGB(subDirectory.FullName))); - return startDirectorySize; //Return full Size of this Directory. } }