Skip to content

Commit

Permalink
add FileAssociation
Browse files Browse the repository at this point in the history
  • Loading branch information
MikiraSora committed Jan 2, 2024
1 parent c9d496c commit 618d0c2
Show file tree
Hide file tree
Showing 7 changed files with 360 additions and 7 deletions.
25 changes: 21 additions & 4 deletions OngekiFumenEditor/AppBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
Expand Down Expand Up @@ -154,14 +155,29 @@ protected void LogBaseInfos()
Log.LogInfo($"User CurrentCulture: {CultureInfo.CurrentCulture}, CurrentUICulture: {CultureInfo.CurrentUICulture}, DefaultThreadCurrentCulture: {CultureInfo.DefaultThreadCurrentCulture}, DefaultThreadCurrentUICulture: {CultureInfo.DefaultThreadCurrentUICulture}");
}

private bool CheckIfAdminPermission()
{
using var identity = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(identity);

return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

protected async override void OnStartup(object sender, StartupEventArgs e)
{
base.OnStartup(sender, e);
InitExceptionCatcher();
LogBaseInfos();

if (CheckIfAdminPermission())
{
Log.LogWarn("Program is within admin permission.");
IoC.Get<WindowTitleHelper>().TitleContent = "(以管理员权限运行)";
}
else
IoC.Get<WindowTitleHelper>().TitleContent = "";

IoC.Get<IShell>().ToolBars.Visible = true;
IoC.Get<WindowTitleHelper>().TitleContent = "";

BitmapImage logo = new BitmapImage();
logo.BeginInit();
Expand Down Expand Up @@ -190,10 +206,11 @@ protected async override void OnStartup(object sender, StartupEventArgs e)
{
window.AllowDrop = true;
window.Drop += MainWindow_Drop;

if (!ProgramSetting.Default.DisableShowSplashScreenAfterBoot)
IoC.Get<IWindowManager>().ShowWindowAsync(IoC.Get<ISplashScreenWindow>());
}

var showSplashWindow = IoC.Get<IShell>().Documents.IsEmpty() && !ProgramSetting.Default.DisableShowSplashScreenAfterBoot;
if (showSplashWindow)
IoC.Get<IWindowManager>().ShowWindowAsync(IoC.Get<ISplashScreenWindow>());

Check warning on line 213 in OngekiFumenEditor/AppBootstrapper.cs

View workflow job for this annotation

GitHub Actions / build

Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
}

private async void MainWindow_Drop(object sender, DragEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using Caliburn.Micro;
using AssocSupport;
using AssocSupport.Models;
using Caliburn.Micro;
using Gemini.Modules.Settings;
using OngekiFumenEditor.Properties;
using OngekiFumenEditor.Utils;
using System;
using System.ComponentModel.Composition;
using System.IO;
using System.Reflection;
using System.Text.Json;
using System.Windows.Forms;

namespace OngekiFumenEditor.Kernel.SettingPages.Program.ViewModels
Expand All @@ -13,7 +17,30 @@ namespace OngekiFumenEditor.Kernel.SettingPages.Program.ViewModels
[PartCreationPolicy(CreationPolicy.Shared)]
public class ProgramSettingViewModel : PropertyChangedBase, ISettingsEditor
{
public Properties.ProgramSetting Setting => Properties.ProgramSetting.Default;
public ProgramSetting Setting => ProgramSetting.Default;

public bool EnableAssociate => !AssociationUtility.IsRegistered("OngekiFumenEditor", "NyagekiFumenProject");

private bool enableAssociateNyagekiProj = true;
public bool EnableAssociateNyagekiProj
{
get => enableAssociateNyagekiProj;
set => Set(ref enableAssociateNyagekiProj, value);
}

private bool enableAssociateNyageki = true;
public bool EnableAssociateNyageki
{
get => enableAssociateNyageki;
set => Set(ref enableAssociateNyageki, value);
}

private bool enableAssociateOgkr = true;
public bool EnableAssociateOgkr
{
get => enableAssociateOgkr;
set => Set(ref enableAssociateOgkr, value);
}

public ProgramSettingViewModel()
{
Expand Down Expand Up @@ -57,5 +84,132 @@ public void ThrowException()
{
throw new Exception("塔塔开!");
}

public async void RegisterNyagekiAssociations()
{
var iconFolder = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "Resources", "FileAssociationIcons");
var iconFilePath = Path.Combine(iconFolder, "icon.ico");

if (!File.Exists(iconFilePath))
{
Directory.CreateDirectory(iconFolder);
var streamInfo = System.Windows.Application.GetResourceStream(new Uri("pack://application:,,,/OngekiFumenEditor;component/Resources/Icons/logo32.ico"));
using var fs = streamInfo.Stream;
using var fs2 = File.OpenWrite(iconFilePath);
await fs.CopyToAsync(fs2);
}

var software = new Software
{
Name = "OngekiFumenEditor",
CompanyName = "NyagekiFumenProject",
Description = "Make Offgeki Great Again!",
Icon = iconFilePath,
};

if (EnableAssociateNyagekiProj)
{
software.Identifiers.Add(new ProgrammaticID
{
Type = new FileType
{
Extension = ".nyagekiProj",
ContentType = "application/sample",
PerceivedType = PerceivedTypes.Application,
},
Command = new ShellCommand
{
Path = Application.ExecutablePath,
Argument = "%1"
},
Description = "Ongeki Fumen Editor Fumen Project File",
Icon = iconFilePath,
});
}

if (EnableAssociateNyageki)
{
software.Identifiers.Add(new ProgrammaticID
{
Type = new FileType
{
Extension = ".nyageki",
ContentType = "application/sample",
PerceivedType = PerceivedTypes.Application,
},
Command = new ShellCommand
{
Path = Application.ExecutablePath,
Argument = "%1"
},
Description = "Ongeki Fumen Editor Fumen File",
Icon = iconFilePath,
});
}

if (EnableAssociateOgkr)
{
software.Identifiers.Add(new ProgrammaticID
{
Type = new FileType
{
Extension = ".ogkr",
ContentType = "application/sample",
PerceivedType = PerceivedTypes.Application,
},
Command = new ShellCommand
{
Path = Application.ExecutablePath,
Argument = "%1"
},
Description = "Ongeki Fumen File",
Icon = iconFilePath,
});
}

if (software.Identifiers.Count == 0)
{
MessageBox.Show(Resources.RegisterOneFileTypeAtLeast, Resources.FileAssociation);
return;
}

try
{
var content = JsonSerializer.Serialize(software);
Log.LogDebug($"software = {content}");

if (AssociationUtility.Register(software))
MessageBox.Show(Resources.RegisterSuccess, Resources.FileAssociation);
else
MessageBox.Show(Resources.RegisterFail, Resources.FileAssociation);
}
catch (UnauthorizedAccessException)
{
MessageBox.Show(Resources.RequestAdminPermission, Resources.FileAssociation);
}

NotifyOfPropertyChange(() => EnableAssociate);
}

public void UnRegisterNyagekiAssociations()
{
try
{
if (AssociationUtility.Unregister("OngekiFumenEditor", "NyagekiFumenProject"))
MessageBox.Show(Resources.UnregisterSuccess, Resources.FileAssociation);
else
MessageBox.Show(Resources.UnregisterFail, Resources.FileAssociation);
}
catch (UnauthorizedAccessException)
{
MessageBox.Show(Resources.RequestAdminPermission, Resources.FileAssociation);
}
catch
{
MessageBox.Show(Resources.UnregisterFail, Resources.FileAssociation);
}

NotifyOfPropertyChange(() => EnableAssociate);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://caliburnmicro.com"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:markup="clr-namespace:OngekiFumenEditor.UI.Markup"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:res="clr-namespace:OngekiFumenEditor.Properties" xmlns:markup="clr-namespace:OngekiFumenEditor.UI.Markup"
xmlns:res="clr-namespace:OngekiFumenEditor.Properties"
xmlns:vm="clr-namespace:OngekiFumenEditor.Kernel.SettingPages.Program.ViewModels"
d:Background="White"
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True,
Expand Down Expand Up @@ -89,5 +90,35 @@
</CheckBox>
</StackPanel>
</GroupBox>
<GroupBox Margin="5" Header="{markup:Translate [FileAssociationRequestAdmin]}">
<StackPanel>
<StackPanel Margin="5" Orientation="Horizontal">
<CheckBox IsChecked="{Binding EnableAssociateNyagekiProj}">
<TextBlock Text=".nyagekiProj" TextWrapping="Wrap" />
</CheckBox>
<CheckBox Margin="10,0" IsChecked="{Binding EnableAssociateNyageki}">
<TextBlock Text=".nyageki" TextWrapping="Wrap" />
</CheckBox>
<CheckBox IsChecked="{Binding EnableAssociateOgkr}">
<TextBlock Text=".ogkr" TextWrapping="Wrap" />
</CheckBox>
</StackPanel>
<StackPanel Margin="5" Orientation="Horizontal">
<Button
Padding="10,5"
HorizontalAlignment="Left"
cal:Message.Attach="RegisterNyagekiAssociations()"
Content="{markup:Translate [FileAssociationRegister]}"
IsEnabled="{Binding EnableAssociate}" />
<Button
Margin="10,0,0,0"
Padding="10,5"
HorizontalAlignment="Left"
cal:Message.Attach="UnRegisterNyagekiAssociations()"
Content="{markup:Translate [FileAssociationUnregister]}"
IsEnabled="{Binding EnableAssociate, Converter={StaticResource ReverseBoolConverter}}" />
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>
</UserControl>
1 change: 1 addition & 0 deletions OngekiFumenEditor/OngekiFumenEditor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@

<ItemGroup>
<PackageReference Include="AssetsTools.NET" Version="2.0.12" />
<PackageReference Include="AssocSupport" Version="1.1.0" />
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
<PackageReference Include="Costura.Fody" Version="5.7.0">
<PrivateAssets>all</PrivateAssets>
Expand Down
Loading

0 comments on commit 618d0c2

Please sign in to comment.