diff --git a/RustTools/App.config b/RustTools/App.config deleted file mode 100644 index 935bcd2..0000000 --- a/RustTools/App.config +++ /dev/null @@ -1,24 +0,0 @@ - - - - -
-
- - - - - - 1 - - - - - 1 - - - - - - - \ No newline at end of file diff --git a/RustTools/App.xaml.cs b/RustTools/App.xaml.cs index 243700f..79b2eef 100644 --- a/RustTools/App.xaml.cs +++ b/RustTools/App.xaml.cs @@ -106,6 +106,8 @@ public partial class App : Microsoft.UI.Xaml.Application Build(); UnhandledException += App_UnhandledException; + + var path = ApplicationData.Current.LocalFolder.Path; var v = Path.Combine(path, "CodeTable"); gj.sc(path); diff --git a/RustTools/RustTools.csproj b/RustTools/RustTools.csproj index 3462999..fb15307 100644 --- a/RustTools/RustTools.csproj +++ b/RustTools/RustTools.csproj @@ -8,7 +8,7 @@ x86;x64;arm64 true - + true win10-x86;win10-x64;win10-arm64 enable @@ -51,6 +51,7 @@ + diff --git a/RustTools/Services/BooleanToVisibilityConverter.cs b/RustTools/Services/BooleanToVisibilityConverter.cs new file mode 100644 index 0000000..fb261c4 --- /dev/null +++ b/RustTools/Services/BooleanToVisibilityConverter.cs @@ -0,0 +1,26 @@ +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Data; + + +namespace RustTools.Services; + +public class BooleanToVisibilityConverter : IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, string language) + { + + return string.IsNullOrEmpty(value.ToString()) ? Visibility.Collapsed: Visibility.Visible; + + + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + if (value is Visibility visibility) + { + return visibility == Visibility.Visible; + } + + return false; + } +} diff --git a/RustTools/Usings.cs b/RustTools/Usings.cs index 4cc487e..99740c7 100644 --- a/RustTools/Usings.cs +++ b/RustTools/Usings.cs @@ -1 +1 @@ -global using WinUIEx; +global using WinUIEx; \ No newline at end of file diff --git a/RustTools/Views/CodeTablePage.xaml b/RustTools/Views/CodeTablePage.xaml index 541ef43..7d3592b 100644 --- a/RustTools/Views/CodeTablePage.xaml +++ b/RustTools/Views/CodeTablePage.xaml @@ -3,6 +3,7 @@ x:Class="RustTools.Views.CodeTablePage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:Services="using:RustTools.Services" xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:datalist="using:RustTools.DataList" @@ -11,6 +12,9 @@ xmlns:themes="using:RustTools.Themes" mc:Ignorable="d"> + + + @@ -122,7 +126,8 @@ Grid.Column="1" VerticalAlignment="Top" Click="List_ButtonIcon_Click" - Glyph="" /> + Glyph="" + Visibility="{Binding demo, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=''}" /> diff --git a/RustTools/Views/ModulePage.xaml b/RustTools/Views/ModulePage.xaml index d05abe0..87c52d5 100644 --- a/RustTools/Views/ModulePage.xaml +++ b/RustTools/Views/ModulePage.xaml @@ -13,14 +13,11 @@ - + - + @@ -107,12 +107,20 @@ + SelectionMode="Single"> + + + diff --git a/RustTools/Views/ModulePage.xaml.cs b/RustTools/Views/ModulePage.xaml.cs index bf679d8..ba702f0 100644 --- a/RustTools/Views/ModulePage.xaml.cs +++ b/RustTools/Views/ModulePage.xaml.cs @@ -2,8 +2,10 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Media; +using Microsoft.VisualBasic.FileIO; using RustTools.muqing; using RustTools.ViewModels; +using SharpCompress.Common; namespace RustTools.Views; /// /// 模组碎片 @@ -110,7 +112,7 @@ public sealed partial class ModulePage : Page /// /// /// - private void Button_Delete(object sender, RoutedEventArgs e) + private async void Button_Delete(object sender, RoutedEventArgs e) { var menuItem = sender as Control; gj.sc(menuItem); @@ -118,15 +120,21 @@ public sealed partial class ModulePage : Page { if (menuItem.DataContext is DataObject folderItem) { - if (Directory.Exists(folderItem.Dri)) + var task = await Dialog.DialogWarnYes("你确定要删除(回收站)" + folderItem.Dri, XamlRoot); + if (task == ContentDialogResult.Primary) { - // 删除文件夹 - Directory.Delete(folderItem.Dri, true); - } - else if (File.Exists(folderItem.Dri)) - { - //删除文件 - File.Delete(folderItem.Dri); + if (Directory.Exists(folderItem.Dri)) + { + // 删除文件夹 + //Directory.Delete(folderItem.Dri, true); + FileSystem.DeleteDirectory(folderItem.Dri, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); + } + else if (File.Exists(folderItem.Dri)) + { + //删除文件 + //File.Delete(folderItem.Dri); + FileSystem.DeleteFile(folderItem.Dri, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); + } } ViewModel.ListMod.Remove(folderItem); } @@ -140,7 +148,7 @@ public sealed partial class ModulePage : Page /// /// /// - private async void Button_Click_RwmodItem(object sender, RoutedEventArgs e) + private async void UnzipRwmod(DataObject a) { ContentDialog dialog = new ContentDialog { @@ -153,33 +161,24 @@ public sealed partial class ModulePage : Page var contentDialogResult = await dialog.ShowAsync(); if (contentDialogResult == ContentDialogResult.Primary) { + var checkbox = (dialog.Content as StackPanel)?.Children[1] as CheckBox; - var button = sender as Button; - if (button != null) + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(a.Dri); + var GetDirectoryName = Path.GetDirectoryName(a.Dri); + if (Directory.Exists(GetDirectoryName) && fileNameWithoutExtension != null) { - var container = VisualTreeHelper.GetParent(button) as FrameworkElement; - if (container != null && container.DataContext is DataObject dataItem) + var targetDirectory = Path.Combine(GetDirectoryName, fileNameWithoutExtension); + var v = wj.UnzipFile(a.Dri, targetDirectory); + gj.sc("解压成功:" + v); + if (checkbox?.IsChecked == true) { - var checkbox = (dialog.Content as StackPanel)?.Children[1] as CheckBox; - - var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(dataItem.Dri); - var GetDirectoryName = Path.GetDirectoryName(dataItem.Dri); - if (Directory.Exists(GetDirectoryName) && fileNameWithoutExtension != null) - { - var targetDirectory = Path.Combine(GetDirectoryName, fileNameWithoutExtension); - var v = wj.UnzipFile(dataItem.Dri, targetDirectory); - gj.sc("解压成功:"+v); - if (checkbox?.IsChecked == true) - { - File.Delete(dataItem.Dri); - ViewModel.ListMod.Remove(dataItem); - } - if (v) - { - ViewModel.ListMod.Remove(new DataObject(new DirectoryInfo(targetDirectory))); - ViewModel.ListMod.Insert(0,new DataObject(new DirectoryInfo(targetDirectory))); - } - } + File.Delete(a.Dri); + ViewModel.ListMod.Remove(a); + } + if (v) + { + ViewModel.ListMod.Remove(new DataObject(new DirectoryInfo(targetDirectory))); + ViewModel.ListMod.Insert(0, new DataObject(new DirectoryInfo(targetDirectory))); } } } @@ -249,6 +248,32 @@ public sealed partial class ModulePage : Page } } + /// + /// 双击GridView事件 + /// + /// + /// + private async void BasicGridView_DoubleTapped(object sender, Microsoft.UI.Xaml.Input.DoubleTappedRoutedEventArgs e) + { + + var gridView = sender as GridView; + var item = (e.OriginalSource as FrameworkElement)?.DataContext; + + if (item != null && gridView != null) + { + // 这里处理双击事件,例如显示一个消息框 + // 替换为实际的数据类型 + if (item is DataObject clickedItem) + { + // 在这里处理双击项 + var IsRwmod = clickedItem.IsRwmod; // 假设你的项有一个 Name 属性 + if (IsRwmod) { + UnzipRwmod(clickedItem); + } + + } + } + } } public class MyItemTemplateSelector : DataTemplateSelector { diff --git a/RustTools/Views/SettingsPage.xaml b/RustTools/Views/SettingsPage.xaml index c3b6a17..88da0a6 100644 --- a/RustTools/Views/SettingsPage.xaml +++ b/RustTools/Views/SettingsPage.xaml @@ -98,10 +98,14 @@ Style="{ThemeResource BodyTextBlockStyle}" /> + diff --git a/RustTools/muqing/Dialog.cs b/RustTools/muqing/Dialog.cs index b75d383..65dbb5d 100644 --- a/RustTools/muqing/Dialog.cs +++ b/RustTools/muqing/Dialog.cs @@ -35,6 +35,7 @@ public class Dialog public const string warning = "警告"; public const string Close = "取消"; + public const string Primary = "确定"; public static async Task DialogWarn(string sub, XamlRoot xamlRoot) { var contentDialog = new ContentDialog() @@ -46,4 +47,24 @@ public class Dialog }; return await contentDialog.ShowAsync(); } + + /// + /// 带有确定按钮的警告 + /// + /// + /// + /// + public static async Task DialogWarnYes(string sub, XamlRoot xamlRoot) + { + var contentDialog = new ContentDialog() + { + XamlRoot = xamlRoot, + Title = warning, + Content = sub, + CloseButtonText = Close, + PrimaryButtonText= Primary, + PrimaryButtonStyle= Application.Current.Resources["AccentButtonStyle"] as Style + }; + return await contentDialog.ShowAsync(); + } } diff --git a/RustTools/muqing/IShellLinkW.cs b/RustTools/muqing/IShellLinkW.cs new file mode 100644 index 0000000..d4ccb65 --- /dev/null +++ b/RustTools/muqing/IShellLinkW.cs @@ -0,0 +1,74 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; + +[ComImport] +[Guid("000214F9-0000-0000-C000-000000000046")] +[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +public interface IShellLinkW +{ + void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref WIN32_FIND_DATAW pfd, uint fFlags); + void GetIDList(out IntPtr ppidl); + void SetIDList(IntPtr pidl); + void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); + void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); + void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); + void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); + void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); + void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); + void GetHotkey(out short pwHotkey); + void SetHotkey(short wHotkey); + void GetShowCmd(out int piShowCmd); + void SetShowCmd(int iShowCmd); + void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath); + void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); + void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved); + void Resolve(IntPtr hwnd, uint fFlags); + void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); +} + +[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)] +public struct WIN32_FIND_DATAW +{ + public uint dwFileAttributes; + public FILETIME ftCreationTime; + public FILETIME ftLastAccessTime; + public FILETIME ftLastWriteTime; + public uint nFileSizeHigh; + public uint nFileSizeLow; + public uint dwReserved0; + public uint dwReserved1; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] + public string cFileName; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] + public string cAlternateFileName; +} + +[StructLayout(LayoutKind.Sequential)] +public struct FILETIME +{ + public uint dwLowDateTime; + public uint dwHighDateTime; +} + +[ComImport] +[Guid("0000010B-0000-0000-C000-000000000046")] +[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +public interface IPersistFile +{ + void GetClassID(out Guid pClassID); + [PreserveSig] + int IsDirty(); + void Load([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode); + void Save([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fRemember); + void SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] string pszFileName); + void GetCurFile([MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName); +} + +[ComImport] +[Guid("00021401-0000-0000-C000-000000000046")] +[ClassInterface(ClassInterfaceType.None)] +public class ShellLink +{ +} + diff --git a/RustTools/muqing/IniHelper.cs b/RustTools/muqing/IniHelper.cs index 49c2416..f91b8c9 100644 --- a/RustTools/muqing/IniHelper.cs +++ b/RustTools/muqing/IniHelper.cs @@ -1,4 +1,5 @@ -using Windows.Storage; +using RustTools.muqing; +using Windows.Storage; #pragma warning disable CA1050 // 在命名空间中声明类型 public class IniHelper diff --git a/RustTools/muqing/mod.cs b/RustTools/muqing/mod.cs index 8127ac1..bcefc11 100644 --- a/RustTools/muqing/mod.cs +++ b/RustTools/muqing/mod.cs @@ -6,21 +6,21 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.Win32; using RustTools.muqing; +/// +/// 模组搜索引擎操作 +/// public class Mod { - - //ʼʱ private static DateTime StartTime; /// - /// ͳкʱ + /// 结束时间 /// private static void EndTime() { - Console.WriteLine("ִʱ䣺" + (DateTime.Now - StartTime).TotalMilliseconds + "ms"); + Console.WriteLine("结束" + (DateTime.Now - StartTime).TotalMilliseconds + "ms"); } - private readonly bool Isdot = true;//Ƿų.ͷļ - //ųļ + private readonly bool Isdot = true; private readonly List ExcludeFile = new(){ "Android", "androidword", "Java", "Linux", "linuxword", "Mac", @@ -28,12 +28,10 @@ public class Mod "Genshin Impact Game", "Godot", "Gradle", "WeGame", "Mental Omega", "WeGameApps", "ramboplayGame", "QQ", "QQWORD","Microsoft SDKs","Creator","editors","AndroidSDK","SDK","Pr","PR","PS","Ps","WE", - "androidstudioword","ͼսƽ̨","xshell7" + "androidstudioword","��ͼ��սƽ̨","xshell7" }; - //Ϸλ public string FileDir = string.Empty; private readonly ContentDialog? dialog = null; - //MainPageĺ̨code public async void Invoke(Action action, Windows.UI.Core.CoreDispatcherPriority Priority = Windows.UI.Core.CoreDispatcherPriority.Normal) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Priority, () => { action(); }); @@ -48,20 +46,16 @@ public class Mod this.xamlRoot = xamlRoot; this.action = action; StartTime = DateTime.Now; - - Debug.WriteLine("ʼִļ"); - //steamеλ steam(); if (FileDir == string.Empty) { - //Ҳִ - gj.sc("Ҳִ"); + dialog = new ContentDialog() { XamlRoot = xamlRoot, - Title = "ʾ", - Content = "", - PrimaryButtonText = "ر" + Title = "提示ʾ", + Content = "搜索中···", + PrimaryButtonText = "取消" }; dialog.Closing += Dialog_Closing; @@ -69,8 +63,6 @@ public class Mod Task.Run(async () => { await init(); - // ʹ DispatcherQueue UI ίл UI ߳ - _dispatcherQueue.TryEnqueue(() => { dialog.Closing -= Dialog_Closing; @@ -78,22 +70,12 @@ public class Mod action?.Invoke(FileDir); }); }); - //if (IsSearch) - //{ - //} - //var thread = new Thread(init); - //thread.Start(); - //thread.Join(); } else { action?.Invoke(FileDir); } - //dialog.Closing -= Dialog_Closing; - //if (FileDir != string.Empty) { - // dialog.Content = FileDir; - //} - //dialog.Hide(); + } @@ -112,23 +94,18 @@ public class Mod var steamPath = GetSteamInstallPath(); if (!string.IsNullOrEmpty(steamPath)) { - Console.WriteLine("Ѿҵsteamװλ" + steamPath); var b = Directory.Exists(steamPath + "\\steamapps\\common\\Rusted Warfare"); if (b) { - //ʱ - Console.WriteLine("ҵϷļ· " + steamPath + "\\steamapps\\common\\Rusted Warfare"); FileDir = steamPath + "\\steamapps\\common\\Rusted Warfare"; EndTime(); } else { - Console.WriteLine("δҵϷļ·"); } } else { - Console.WriteLine("Ҳsteamİװλ"); } } @@ -139,7 +116,6 @@ public class Mod foreach (var d in allDrives) { Console.WriteLine(); - // Console.WriteLine(" Drive type: {0}", d.DriveType); if (d.IsReady == true) { var name = d.Name; @@ -147,20 +123,15 @@ public class Mod { continue; } - //ֻҪC + if (name.Equals("C:\\")) { - Debug.WriteLine("CϷļ·"); FileSearch(name); } else { - Debug.WriteLine("пϷļ·"); - // steam\steamapps\common\Rusted Warfare - // new FileSearch(name).Search(); if (Directory.Exists(name + "/Rusted Warfare")) { - Debug.WriteLine("ҵϷļ·"); EndTime(); break; } @@ -174,42 +145,28 @@ public class Mod } } - //Ƿ public bool IsSearch = true; private void FileSearch(string path) { - Debug.WriteLine("ʼļ" + path); try { - // ļ foreach (var file in Directory.EnumerateDirectories(path)) { if (!IsSearch) { return; } - //ųŵļ - // if (file.contains("$")) - // { - // Console.WriteLine("ųſͷļ" + file); - // continue; - // } - //ų.ͷļ var name = Path.GetFileName(file); if (Isdot && name.StartsWith(".")) { - Debug.WriteLine("ųͷļ" + file); continue; } - //ųбеļ if (ExcludeFile.Contains(name)) { - Debug.WriteLine("ųбеļ" + file); continue; } if (name.Equals("Rusted Warfare")) { - Debug.WriteLine("ҵϷļ·" + file); FileDir = file; EndTime(); break; @@ -223,12 +180,10 @@ public class Mod } catch (UnauthorizedAccessException) { - // ʱܾļв¼Ϣ Console.WriteLine($"Access denied for: {path}"); } catch (Exception ex) { - // ܵ쳣 Console.WriteLine($"Error accessing directory '{path}': {ex.Message}"); } } @@ -240,7 +195,6 @@ public class Mod if (string.IsNullOrEmpty(installPath)) { - // ڵǰûҲһû installPath = GetInstallPathFromKey(@"SOFTWARE\Wow6432Node\Valve\Steam"); } @@ -252,7 +206,7 @@ public class Mod { if (key != null) { - object path = key.GetValue("InstallPath"); + var path = key.GetValue("InstallPath"); if (path != null) { return (string)path; @@ -260,7 +214,7 @@ public class Mod } } - using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subKey)) + using (var key = Registry.LocalMachine.OpenSubKey(subKey)) { if (key != null) { @@ -272,7 +226,7 @@ public class Mod } } - return null; + return string.Empty; } } } \ No newline at end of file