diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/FileOperation.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/FileOperation.cs index e7677801..5b80fd6f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/IO/FileOperation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/FileOperation.cs @@ -1,7 +1,13 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Win32.Foundation; +using Snap.Hutao.Win32.System.Com; +using Snap.Hutao.Win32.UI.Shell; using System.IO; +using static Snap.Hutao.Win32.Macros; +using static Snap.Hutao.Win32.Ole32; +using static Snap.Hutao.Win32.Shell32; namespace Snap.Hutao.Core.IO; @@ -39,4 +45,57 @@ internal static class FileOperation File.Move(sourceFileName, destFileName, false); return true; } + + public static unsafe bool UnsafeMove(string sourceFileName, string destFileName) + { + bool result = false; + + if (SUCCEEDED(CoCreateInstance(in Win32.UI.Shell.FileOperation.CLSID, default, CLSCTX.CLSCTX_INPROC_SERVER, in IFileOperation.IID, out IFileOperation* pFileOperation))) + { + if (SUCCEEDED(SHCreateItemFromParsingName(sourceFileName, default, in IShellItem.IID, out IShellItem* pSourceShellItem))) + { + if (SUCCEEDED(SHCreateItemFromParsingName(destFileName, default, in IShellItem.IID, out IShellItem* pDestShellItem))) + { + pFileOperation->MoveItem(pSourceShellItem, pDestShellItem, default, default); + + if (SUCCEEDED(pFileOperation->PerformOperations())) + { + result = true; + } + + pDestShellItem->Release(); + } + + pSourceShellItem->Release(); + } + + pFileOperation->Release(); + } + + return result; + } + + public static unsafe bool UnsafeDelete(string path) + { + bool result = false; + + if (SUCCEEDED(CoCreateInstance(in Win32.UI.Shell.FileOperation.CLSID, default, CLSCTX.CLSCTX_INPROC_SERVER, in IFileOperation.IID, out IFileOperation* pFileOperation))) + { + if (SUCCEEDED(SHCreateItemFromParsingName(path, default, in IShellItem.IID, out IShellItem* pShellItem))) + { + pFileOperation->DeleteItem(pShellItem, default); + + if (SUCCEEDED(pFileOperation->PerformOperations())) + { + result = true; + } + + pShellItem->Release(); + } + + pFileOperation->Release(); + } + + return result; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/Hash.cs b/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/Hash.cs index 49d67a36..f3eb6e5f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/Hash.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/IO/Hashing/Hash.cs @@ -10,7 +10,7 @@ internal static class Hash { public static string SHA1HexString(string input) { - return HashCore(BitConverter.ToString, SHA1.HashData, Encoding.UTF8.GetBytes, input); + return HashCore(System.Convert.ToHexString, SHA1.HashData, Encoding.UTF8.GetBytes, input); } private static TResult HashCore(Func resultConverter, Func hashMethod, Func bytesConverter, TInput input) diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx index 49fdaf68..c45d3eb4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx @@ -1724,6 +1724,9 @@ 无感验证复合 Url 配置成功 + + 正在重置图片资源 + 设置数据目录成功,重启以应用更改 diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs index f81f7909..4db47dc9 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Setting/SettingViewModel.cs @@ -5,7 +5,9 @@ using CommunityToolkit.Mvvm.Messaging; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.Windows.AppLifecycle; +using Snap.Hutao.Control.Extension; using Snap.Hutao.Core; +using Snap.Hutao.Core.Caching; using Snap.Hutao.Core.Setting; using Snap.Hutao.Core.Shell; using Snap.Hutao.Core.Windowing; @@ -220,14 +222,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel return ValueTask.FromResult(true); } - [Command("ResetStaticResourceCommand")] - private static void ResetStaticResource() - { - StaticResource.FailAll(); - UnsafeLocalSetting.Set(SettingKeys.Major1Minor10Revision0GuideState, GuideState.StaticResourceBegin); - AppInstance.Restart(string.Empty); - } - [Command("StoreReviewCommand")] private static async Task StoreReviewAsync() { @@ -240,6 +234,24 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel await Launcher.LaunchUriAsync(new("ms-windows-store://pdp/?productid=9PH4NXJ2JN52")); } + [Command("ResetStaticResourceCommand")] + private async Task ResetStaticResource() + { + ContentDialog dialog = await contentDialogFactory + .CreateForIndeterminateProgressAsync(SH.ViewModelSettingResetStaticResourceProgress) + .ConfigureAwait(false); + + await using (await dialog.BlockAsync(taskContext).ConfigureAwait(false)) + { + await taskContext.SwitchToBackgroundAsync(); + StaticResource.FailAll(); + Directory.Delete(Path.Combine(runtimeOptions.LocalCache, nameof(ImageCache)), true); + UnsafeLocalSetting.Set(SettingKeys.Major1Minor10Revision0GuideState, GuideState.StaticResourceBegin); + } + + AppInstance.Restart(string.Empty); + } + [Command("DeleteGameWebCacheCommand")] private void DeleteGameWebCache() { diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/UI/Shell/FileOperation.cs b/src/Snap.Hutao/Snap.Hutao/Win32/UI/Shell/FileOperation.cs new file mode 100644 index 00000000..2178bb34 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Win32/UI/Shell/FileOperation.cs @@ -0,0 +1,20 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Snap.Hutao.Win32.UI.Shell; + +[Guid("3AD05575-8857-4850-9277-11B85BDB8E09")] +internal readonly struct FileOperation +{ + internal static unsafe ref readonly Guid CLSID + { + get + { + ReadOnlySpan data = [0x75, 0x55, 0xD0, 0x3A, 0x57, 0x88, 0x50, 0x48, 0x92, 0x77, 0x11, 0xB8, 0x5B, 0xDB, 0x8E, 0x09]; + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/UI/Shell/IFileOperation.cs b/src/Snap.Hutao/Snap.Hutao/Win32/UI/Shell/IFileOperation.cs index db14bbe7..9850974e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Win32/UI/Shell/IFileOperation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Win32/UI/Shell/IFileOperation.cs @@ -47,6 +47,24 @@ internal unsafe struct IFileOperation return ThisPtr->IUnknownVftbl.Release((IUnknown*)Unsafe.AsPointer(ref this)); } + public unsafe HRESULT DeleteItem(IShellItem* psiItem, IFileOperationProgressSink* pfopsItem) + { + return ThisPtr->DeleteItem((IFileOperation*)Unsafe.AsPointer(ref this), psiItem, pfopsItem); + } + + public unsafe HRESULT MoveItem(IShellItem* psiItem, IShellItem* psiDestinationFolder, [AllowNull] string szNewName, IFileOperationProgressSink* pfopsItem) + { + fixed (char* pszNewName = szNewName) + { + return ThisPtr->MoveItem((IFileOperation*)Unsafe.AsPointer(ref this), psiItem, psiDestinationFolder, pszNewName, pfopsItem); + } + } + + public unsafe HRESULT PerformOperations() + { + return ThisPtr->PerformOperations((IFileOperation*)Unsafe.AsPointer(ref this)); + } + internal readonly struct Vftbl { internal readonly IUnknown.Vftbl IUnknownVftbl;