direct set registry value

This commit is contained in:
DismissedLight
2023-12-24 13:52:06 +08:00
parent 3ffdc901c7
commit 93077104b8
7 changed files with 28 additions and 69 deletions

View File

@@ -15,9 +15,6 @@ internal sealed partial class SettingEntry
public const string GamePathEntries = "GamePathEntries";
/// <summary>
/// PowerShell 路径
/// </summary>
public const string PowerShellPath = "PowerShellPath";
/// <summary>

View File

@@ -2436,7 +2436,7 @@
<value>设置游戏路径时请选择游戏本体YuanShen.exe 或 GenshinImpact.exe而不是启动器launcher.exe</value>
</data>
<data name="ViewPageSettingSetPowerShellDescription" xml:space="preserve">
<value>胡桃使用 PowerShell 更改注册表中的信息以修改游戏内账号</value>
<value>在创建的快捷方式中启动胡桃需要使用 PowerShell</value>
</data>
<data name="ViewPageSettingSetPowerShellPathHeader" xml:space="preserve">
<value>PowerShell 路径</value>

View File

@@ -16,7 +16,6 @@ internal sealed partial class GameAccountService : IGameAccountService
private readonly IContentDialogFactory contentDialogFactory;
private readonly IGameDbService gameDbService;
private readonly ITaskContext taskContext;
private readonly AppOptions appOptions;
private ObservableCollection<GameAccount>? gameAccounts;
@@ -90,12 +89,7 @@ internal sealed partial class GameAccountService : IGameAccountService
public bool SetGameAccount(GameAccount account)
{
if (string.IsNullOrEmpty(appOptions.PowerShellPath))
{
ThrowHelper.RuntimeEnvironment(SH.ServiceGameRegisteryInteropPowershellNotFound, default!);
}
return RegistryInterop.Set(account, appOptions.PowerShellPath);
return RegistryInterop.Set(account);
}
public void AttachGameAccountToUid(GameAccount gameAccount, string uid)

View File

@@ -20,48 +20,16 @@ internal static class RegistryInterop
private const string GenshinKey = $@"HKEY_CURRENT_USER\{GenshinPath}";
private const string SdkChineseKey = "MIHOYOSDK_ADL_PROD_CN_h3123967166";
/// <summary>
/// 设置键值
/// 需要支持
/// https://learn.microsoft.com/zh-cn/windows/win32/fileio/maximum-file-path-limitation
/// </summary>
/// <param name="account">账户</param>
/// <param name="powerShellPath">PowerShell 路径</param>
/// <returns>账号是否设置</returns>
public static bool Set(GameAccount? account, string powerShellPath)
public static bool Set(GameAccount? account)
{
if (account is not null)
{
// 存回注册表的字节需要 '\0' 结尾
Encoding.UTF8.GetByteCount(account.MihoyoSDK);
byte[] tempBytes = Encoding.UTF8.GetBytes(account.MihoyoSDK);
byte[] target = new byte[tempBytes.Length + 1];
tempBytes.CopyTo(target, 0);
byte[] target = [.. Encoding.UTF8.GetBytes(account.MihoyoSDK), 0];
Registry.SetValue(GenshinKey, SdkChineseKey, target);
string base64 = Convert.ToBase64String(target);
string path = $"HKCU:{GenshinPath}";
string command = $"""
-Command "$value = [Convert]::FromBase64String('{base64}'); Set-ItemProperty -Path '{path}' -Name '{SdkChineseKey}' -Value $value -Force;"
""";
ProcessStartInfo startInfo = new()
{
Arguments = command,
WorkingDirectory = Path.GetDirectoryName(powerShellPath),
CreateNoWindow = true,
FileName = powerShellPath,
};
try
{
System.Diagnostics.Process.Start(startInfo)?.WaitForExit();
}
catch (Win32Exception ex)
{
ThrowHelper.RuntimeEnvironment(SH.ServiceGameRegisteryInteropLongPathsDisabled, ex);
}
if (Get() == account.MihoyoSDK)
string? get = Get();
if (get == account.MihoyoSDK)
{
return true;
}
@@ -70,10 +38,6 @@ internal static class RegistryInterop
return false;
}
/// <summary>
/// 在注册表中获取账号信息
/// </summary>
/// <returns>当前注册表中的信息</returns>
public static unsafe string? Get()
{
object? sdk = Registry.GetValue(GenshinKey, SdkChineseKey, Array.Empty<byte>());

View File

@@ -189,7 +189,20 @@
Header="{shcm:ResourceString Name=ViewPageSettingCreateDesktopShortcutHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE7EF;}"
IsClickEnabled="True"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingSetGamePathAction}"
Command="{Binding SetPowerShellPathCommand}"
Header="{shcm:ResourceString Name=ViewPageSettingSetPowerShellPathHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE756;}"
IsClickEnabled="True">
<cwc:SettingsCard.Description>
<StackPanel>
<TextBlock Text="{shcm:ResourceString Name=ViewPageSettingSetPowerShellDescription}"/>
<TextBlock Text="{Binding AppOptions.PowerShellPath}"/>
</StackPanel>
</cwc:SettingsCard.Description>
</cwc:SettingsCard>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingApperanceHeader}"/>
<cwc:SettingsCard
Description="{shcm:ResourceString Name=ViewPageSettingApperanceLanguageDescription}"
@@ -308,20 +321,6 @@
</cwc:SettingsCard>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingGameHeader}"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingSetGamePathAction}"
Command="{Binding SetPowerShellPathCommand}"
Header="{shcm:ResourceString Name=ViewPageSettingSetPowerShellPathHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE756;}"
IsClickEnabled="True">
<cwc:SettingsCard.Description>
<StackPanel>
<TextBlock Text="{shcm:ResourceString Name=ViewPageSettingSetPowerShellDescription}"/>
<TextBlock Text="{Binding AppOptions.PowerShellPath}"/>
</StackPanel>
</cwc:SettingsCard.Description>
</cwc:SettingsCard>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingDeleteCacheAction}"

View File

@@ -23,9 +23,7 @@ using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.IO;
using Windows.Win32;
using Windows.Win32.Foundation;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.ViewModel.Game;

View File

@@ -6,6 +6,7 @@ using Snap.Hutao.Model.Entity;
using Snap.Hutao.Service.Game;
using Snap.Hutao.Service.Notification;
using System.Collections.ObjectModel;
using Windows.Win32.Foundation;
namespace Snap.Hutao.ViewModel.Game;
@@ -71,6 +72,12 @@ internal sealed partial class LaunchGameViewModelSlim : Abstraction.ViewModelSli
}
catch (Exception ex)
{
if (ex is Win32Exception win32Exception && win32Exception.HResult == HRESULT.E_FAIL)
{
// User canceled the operation. ignore
return;
}
infoBarService.Error(ex);
}
}