增加文件关联首选项
This commit is contained in:
@@ -20,7 +20,8 @@ namespace SpineViewer
|
|||||||
{
|
{
|
||||||
public const string ProgId = "SpineViewer.skel";
|
public const string ProgId = "SpineViewer.skel";
|
||||||
|
|
||||||
public static readonly string ExeFilePath = Environment.ProcessPath;
|
public static readonly string ProcessPath = Environment.ProcessPath;
|
||||||
|
public static readonly string ProcessDirectory = Path.GetDirectoryName(Environment.ProcessPath);
|
||||||
public static readonly string ProcessName = Process.GetCurrentProcess().ProcessName;
|
public static readonly string ProcessName = Process.GetCurrentProcess().ProcessName;
|
||||||
public static readonly string Version = Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
public static readonly string Version = Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ namespace SpineViewer.Models
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _renderSelectedOnly;
|
private bool _renderSelectedOnly;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _associateFileSuffix;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AppLanguage _appLanguage;
|
private AppLanguage _appLanguage;
|
||||||
|
|
||||||
|
|||||||
BIN
SpineViewer/Resources/Images/skel.ico
Normal file
BIN
SpineViewer/Resources/Images/skel.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 191 KiB |
BIN
SpineViewer/Resources/Images/skel.png
Normal file
BIN
SpineViewer/Resources/Images/skel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 188 KiB |
BIN
SpineViewer/Resources/Images/spineviewer.png
Normal file
BIN
SpineViewer/Resources/Images/spineviewer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
@@ -233,6 +233,7 @@
|
|||||||
<s:String x:Key="Str_RendererPreference">Preview Options</s:String>
|
<s:String x:Key="Str_RendererPreference">Preview Options</s:String>
|
||||||
|
|
||||||
<s:String x:Key="Str_AppPreference">Application Options</s:String>
|
<s:String x:Key="Str_AppPreference">Application Options</s:String>
|
||||||
|
<s:String x:Key="Str_AssociateFileSuffix">Associate File Extension</s:String>
|
||||||
<s:String x:Key="Str_Language">Language</s:String>
|
<s:String x:Key="Str_Language">Language</s:String>
|
||||||
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
@@ -233,6 +233,7 @@
|
|||||||
<s:String x:Key="Str_RendererPreference">プレビュー画面オプション</s:String>
|
<s:String x:Key="Str_RendererPreference">プレビュー画面オプション</s:String>
|
||||||
|
|
||||||
<s:String x:Key="Str_AppPreference">アプリケーションプション</s:String>
|
<s:String x:Key="Str_AppPreference">アプリケーションプション</s:String>
|
||||||
|
<s:String x:Key="Str_AssociateFileSuffix">ファイル拡張子を関連付ける</s:String>
|
||||||
<s:String x:Key="Str_Language">言語</s:String>
|
<s:String x:Key="Str_Language">言語</s:String>
|
||||||
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|||||||
@@ -233,6 +233,7 @@
|
|||||||
<s:String x:Key="Str_RendererPreference">预览画面选项</s:String>
|
<s:String x:Key="Str_RendererPreference">预览画面选项</s:String>
|
||||||
|
|
||||||
<s:String x:Key="Str_AppPreference">应用程序选项</s:String>
|
<s:String x:Key="Str_AppPreference">应用程序选项</s:String>
|
||||||
|
<s:String x:Key="Str_AssociateFileSuffix">关联文件后缀</s:String>
|
||||||
<s:String x:Key="Str_Language">语言</s:String>
|
<s:String x:Key="Str_Language">语言</s:String>
|
||||||
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
@@ -14,12 +14,15 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<NoWarn>$(NoWarn);NETSDK1206</NoWarn>
|
<NoWarn>$(NoWarn);NETSDK1206</NoWarn>
|
||||||
<ApplicationIcon>appicon.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\spineviewer.ico</ApplicationIcon>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="appicon.ico" />
|
<Content Include="Resources\Images\skel.ico">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Resources\Images\spineviewer.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using Microsoft.Win32;
|
||||||
using NLog;
|
using NLog;
|
||||||
using Spine.SpineWrappers;
|
using Spine.SpineWrappers;
|
||||||
using SpineViewer.Models;
|
using SpineViewer.Models;
|
||||||
|
using SpineViewer.Natives;
|
||||||
using SpineViewer.Services;
|
using SpineViewer.Services;
|
||||||
using SpineViewer.Utils;
|
using SpineViewer.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -23,6 +26,10 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string PreferenceFilePath = Path.Combine(Path.GetDirectoryName(Environment.ProcessPath), "preference.json");
|
public static readonly string PreferenceFilePath = Path.Combine(Path.GetDirectoryName(Environment.ProcessPath), "preference.json");
|
||||||
|
|
||||||
|
private static readonly string SkelFileDescription = "SpineViewer File";
|
||||||
|
private static readonly string SkelIconFilePath = Path.Combine(App.ProcessDirectory, "Resources\\Images\\skel.ico");
|
||||||
|
private static readonly string ShellOpenCommand = $"\"{App.ProcessPath}\" \"%1\"";
|
||||||
|
|
||||||
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private readonly MainWindowViewModel _vmMain;
|
private readonly MainWindowViewModel _vmMain;
|
||||||
@@ -63,8 +70,19 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void LoadPreference()
|
public void LoadPreference()
|
||||||
{
|
{
|
||||||
if (JsonHelper.Deserialize<PreferenceModel>(PreferenceFilePath, out var obj, true))
|
if (JsonHelper.Deserialize<PreferenceModel>(PreferenceFilePath, out var obj, true))
|
||||||
Preference = obj;
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Preference = obj;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
|
||||||
|
_logger.Trace(ex.ToString());
|
||||||
|
_logger.Error("Failed to load some prefereneces, {0}", ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -94,6 +112,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
DebugClippings = DebugClippings,
|
DebugClippings = DebugClippings,
|
||||||
|
|
||||||
RenderSelectedOnly = RenderSelectedOnly,
|
RenderSelectedOnly = RenderSelectedOnly,
|
||||||
|
AssociateFileSuffix = AssociateFileSuffix,
|
||||||
AppLanguage = AppLanguage,
|
AppLanguage = AppLanguage,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -118,6 +137,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
DebugClippings = value.DebugClippings;
|
DebugClippings = value.DebugClippings;
|
||||||
|
|
||||||
RenderSelectedOnly = value.RenderSelectedOnly;
|
RenderSelectedOnly = value.RenderSelectedOnly;
|
||||||
|
AssociateFileSuffix = value.AssociateFileSuffix;
|
||||||
AppLanguage = value.AppLanguage;
|
AppLanguage = value.AppLanguage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,6 +250,71 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
set => SetProperty(_vmMain.SFMLRendererViewModel.RenderSelectedOnly, value, v => _vmMain.SFMLRendererViewModel.RenderSelectedOnly = v);
|
set => SetProperty(_vmMain.SFMLRendererViewModel.RenderSelectedOnly, value, v => _vmMain.SFMLRendererViewModel.RenderSelectedOnly = v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AssociateFileSuffix
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 检查 .skel 的 ProgID
|
||||||
|
using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Classes\.skel"))
|
||||||
|
{
|
||||||
|
var progIdValue = key?.GetValue("") as string;
|
||||||
|
if (!string.Equals(progIdValue, App.ProgId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 command 指令是否相同
|
||||||
|
using (var key = Registry.CurrentUser.OpenSubKey($@"Software\Classes\{App.ProgId}\shell\open\command"))
|
||||||
|
{
|
||||||
|
var command = key?.GetValue("") as string;
|
||||||
|
if (string.IsNullOrWhiteSpace(command))
|
||||||
|
return false;
|
||||||
|
return command == ShellOpenCommand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetProperty(AssociateFileSuffix, value, v =>
|
||||||
|
{
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
// 文件关联
|
||||||
|
using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\.skel"))
|
||||||
|
{
|
||||||
|
key?.SetValue("", App.ProgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var key = Registry.CurrentUser.CreateSubKey($@"Software\Classes\{App.ProgId}"))
|
||||||
|
{
|
||||||
|
key?.SetValue("", SkelFileDescription);
|
||||||
|
using (var iconKey = key?.CreateSubKey("DefaultIcon"))
|
||||||
|
{
|
||||||
|
iconKey?.SetValue("", $"\"{SkelIconFilePath}\"");
|
||||||
|
}
|
||||||
|
using (var shellKey = key?.CreateSubKey(@"shell\open\command"))
|
||||||
|
{
|
||||||
|
shellKey?.SetValue("", ShellOpenCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 删除关联
|
||||||
|
Registry.CurrentUser.DeleteSubKeyTree(@"Software\Classes\.skel", false);
|
||||||
|
Registry.CurrentUser.DeleteSubKeyTree($@"Software\Classes\{App.ProgId}", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shell32.SHChangeNotify(Shell32.SHCNE_ASSOCCHANGED, Shell32.SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AppLanguage AppLanguage
|
public AppLanguage AppLanguage
|
||||||
{
|
{
|
||||||
get => ((App)App.Current).Language;
|
get => ((App)App.Current).Language;
|
||||||
|
|||||||
@@ -143,13 +143,17 @@
|
|||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource Str_RenderSelectedOnly}"/>
|
<Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource Str_RenderSelectedOnly}"/>
|
||||||
<ToggleButton Grid.Row="0" Grid.Column="1" IsChecked="{Binding RenderSelectedOnly}"/>
|
<ToggleButton Grid.Row="0" Grid.Column="1" IsChecked="{Binding RenderSelectedOnly}"/>
|
||||||
|
|
||||||
<Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource Str_Language}"/>
|
<Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource Str_AssociateFileSuffix}"/>
|
||||||
<ComboBox Grid.Row="1" Grid.Column="1"
|
<ToggleButton Grid.Row="1" Grid.Column="1" IsChecked="{Binding AssociateFileSuffix}"/>
|
||||||
|
|
||||||
|
<Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource Str_Language}"/>
|
||||||
|
<ComboBox Grid.Row="2" Grid.Column="1"
|
||||||
SelectedItem="{Binding AppLanguage}"
|
SelectedItem="{Binding AppLanguage}"
|
||||||
ItemsSource="{x:Static vm:PreferenceViewModel.AppLanguageOptions}"/>
|
ItemsSource="{x:Static vm:PreferenceViewModel.AppLanguageOptions}"/>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user