Ionite
1 year ago
17 changed files with 495 additions and 25 deletions
@ -0,0 +1,102 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
using System.Diagnostics.CodeAnalysis; |
||||
using System.IO; |
||||
using System.Runtime.Versioning; |
||||
using System.Text.Json; |
||||
using System.Threading.Tasks; |
||||
using MessagePipe; |
||||
using Microsoft.Extensions.DependencyInjection; |
||||
using Microsoft.Win32; |
||||
using StabilityMatrix.Core.Helper; |
||||
using URIScheme; |
||||
|
||||
namespace StabilityMatrix.Avalonia.Helpers; |
||||
|
||||
/// <summary> |
||||
/// Custom URI scheme handler for the stabilitymatrix:// protocol |
||||
/// </summary> |
||||
/// <remarks>Need to call <see cref="RegisterUriScheme"/> on App startup</remarks> |
||||
public class UriHandler |
||||
{ |
||||
public const string IpcKeySend = "uri_handler_send"; |
||||
|
||||
public string Scheme { get; } |
||||
public string Description { get; } |
||||
|
||||
public UriHandler(string scheme, string description) |
||||
{ |
||||
Scheme = scheme; |
||||
Description = description; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Send a received Uri over MessagePipe and exits |
||||
/// </summary> |
||||
/// <param name="uri"></param> |
||||
[DoesNotReturn] |
||||
public void SendAndExit(Uri uri) |
||||
{ |
||||
var services = new ServiceCollection(); |
||||
services.AddMessagePipe(); |
||||
services.AddMessagePipeNamedPipeInterprocess("StabilityMatrix"); |
||||
|
||||
var provider = services.BuildServiceProvider(); |
||||
var publisher = provider.GetRequiredService<IDistributedPublisher<string, Uri>>(); |
||||
|
||||
var sendTask = Task.Run(async () => await publisher.PublishAsync(IpcKeySend, uri)); |
||||
sendTask.Wait(); |
||||
|
||||
var info = JsonSerializer.Serialize(new Dictionary<string, Uri> { [IpcKeySend] = uri }); |
||||
|
||||
Debug.WriteLine(info); |
||||
Console.WriteLine(info); |
||||
|
||||
Environment.Exit(0); |
||||
} |
||||
|
||||
public void Callback() { } |
||||
|
||||
public void RegisterUriScheme() |
||||
{ |
||||
if (Compat.IsWindows) |
||||
{ |
||||
RegisterUriSchemeWin(); |
||||
} |
||||
else |
||||
{ |
||||
RegisterUriSchemeUnix(); |
||||
} |
||||
} |
||||
|
||||
[SupportedOSPlatform("windows")] |
||||
private void RegisterUriSchemeWin() |
||||
{ |
||||
using var key = Registry.CurrentUser.CreateSubKey(@$"SOFTWARE\Classes\{Scheme}"); |
||||
|
||||
key.SetValue("", "URL:" + Description); |
||||
key.SetValue(null, Description); |
||||
key.SetValue("URL Protocol", ""); |
||||
|
||||
using (var defaultIcon = key.CreateSubKey("DefaultIcon")) |
||||
{ |
||||
defaultIcon.SetValue("", Compat.AppCurrentPath.FullPath + ",1"); |
||||
} |
||||
|
||||
using (var commandKey = key.CreateSubKey(@"shell\open\command")) |
||||
{ |
||||
commandKey.SetValue("", "\"" + Compat.AppCurrentPath.FullPath + "\" --uri \"%1\""); |
||||
} |
||||
} |
||||
|
||||
private void RegisterUriSchemeUnix() |
||||
{ |
||||
var service = URISchemeServiceFactory.GetURISchemeSerivce( |
||||
Scheme, |
||||
Description, |
||||
Compat.AppCurrentPath.FullPath |
||||
); |
||||
service.Set(); |
||||
} |
||||
} |
@ -0,0 +1,25 @@
|
||||
using System.Web; |
||||
|
||||
namespace StabilityMatrix.Core.Extensions; |
||||
|
||||
public static class UriExtensions |
||||
{ |
||||
public static Uri WithQuery(this Uri uri, string key, string value) |
||||
{ |
||||
var builder = new UriBuilder(uri); |
||||
var query = HttpUtility.ParseQueryString(builder.Query); |
||||
query[key] = value; |
||||
builder.Query = query.ToString() ?? string.Empty; |
||||
return builder.Uri; |
||||
} |
||||
|
||||
public static Uri Append(this Uri uri, params string[] paths) |
||||
{ |
||||
return new Uri( |
||||
paths.Aggregate( |
||||
uri.AbsoluteUri, |
||||
(current, path) => $"{current.TrimEnd('/')}/{path.TrimStart('/')}" |
||||
) |
||||
); |
||||
} |
||||
} |
Loading…
Reference in new issue