Winify

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 60  →  ?path2? @ 61
/trunk/Winify/Gotify/GotifyConnection.cs
@@ -1,19 +1,28 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Caching;
using System.Runtime.CompilerServices;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
using Newtonsoft.Json;
using Serilog;
using Servers;
using WebSocketSharp;
using WebSocketSharp.Net;
using Winify.Utilities;
using ErrorEventArgs = WebSocketSharp.ErrorEventArgs;
using NetworkCredential = System.Net.NetworkCredential;
 
@@ -45,7 +54,15 @@
private WebSocket _webSocketSharp;
private readonly Configuration.Configuration _configuration;
private Task _initTask;
private IDisposable _tplRetrievePastMessagesLink;
private IDisposable _tplWebSocketsBufferBlockTransformLink;
private IDisposable _tplWebSocketsTransformActionLink;
private IDisposable _tplWebSocketsTransformActionNullLink;
private readonly BufferBlock<byte[]> _webSocketMessageBufferBlock;
private readonly Stopwatch _webSocketsClientPingStopWatch;
private readonly ScheduledContinuation _webSocketsServerResponseScheduledContinuation;
 
private readonly MemoryCache _applicationImageCache;
#endregion
 
#region Constructors, Destructors and Finalizers
@@ -52,6 +69,86 @@
 
private GotifyConnection()
{
_applicationImageCache = new MemoryCache("GotifyApplicationImageCache");
_webSocketsServerResponseScheduledContinuation = new ScheduledContinuation();
_webSocketsClientPingStopWatch = new Stopwatch();
 
_webSocketMessageBufferBlock = new BufferBlock<byte[]>(new DataflowBlockOptions { CancellationToken = _cancellationToken });
var webSocketTransformBlock = new TransformBlock<byte[], GotifyMessage>(bytes =>
{
if (bytes.Length == 0)
{
return null;
}
 
var message = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
 
GotifyMessage gotifyNotification;
 
try
{
gotifyNotification = JsonConvert.DeserializeObject<GotifyMessage>(message);
}
catch (JsonSerializationException exception)
{
Log.Warning($"Could not deserialize notification: {exception.Message}");
 
return null;
}
 
if (gotifyNotification == null)
{
Log.Warning($"Could not deserialize gotify notification: {message}");
 
return null;
}
 
return gotifyNotification;
 
}, new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken });
 
var webSocketActionBlock = new ActionBlock<GotifyMessage>(async message =>
{
message.Server = _server;
 
var cachedImage = _applicationImageCache.Get($"{message.AppId}");
if (cachedImage is Image applicationImage)
{
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(message, applicationImage));
return;
}
 
using (var imageStream = await RetrieveGotifyApplicationImage(message.AppId, _cancellationToken))
{
if (imageStream == null || imageStream.Length == 0)
{
Log.Warning("Could not find any application image for notification");
return;
}
 
var image = Image.FromStream(imageStream);
 
_applicationImageCache.Add($"{message.AppId}", image.Clone(),
new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromHours(1)
});
 
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(message, image));
}
 
Log.Debug($"Notification message received: {message.Message}");
 
}, new ExecutionDataflowBlockOptions { CancellationToken = _cancellationToken });
 
_tplWebSocketsBufferBlockTransformLink = _webSocketMessageBufferBlock.LinkTo(webSocketTransformBlock,
new DataflowLinkOptions { PropagateCompletion = true });
_tplWebSocketsTransformActionLink = webSocketTransformBlock.LinkTo(webSocketActionBlock,
new DataflowLinkOptions { PropagateCompletion = true }, message => message != null);
_tplWebSocketsTransformActionNullLink = webSocketTransformBlock.LinkTo(DataflowBlock.NullTarget<GotifyMessage>(),
new DataflowLinkOptions() { PropagateCompletion = true });
}
 
public GotifyConnection(Server server, Configuration.Configuration configuration) : this()
@@ -119,6 +216,30 @@
_cancellationTokenSource = null;
}
 
if (_tplWebSocketsBufferBlockTransformLink != null)
{
_tplWebSocketsBufferBlockTransformLink.Dispose();
_tplWebSocketsBufferBlockTransformLink = null;
}
 
if (_tplWebSocketsTransformActionLink != null)
{
_tplWebSocketsTransformActionLink.Dispose();
_tplWebSocketsTransformActionLink = null;
}
 
if (_tplWebSocketsTransformActionNullLink != null)
{
_tplWebSocketsTransformActionNullLink.Dispose();
_tplWebSocketsTransformActionNullLink = null;
}
 
if (_tplRetrievePastMessagesLink != null)
{
_tplRetrievePastMessagesLink.Dispose();
_tplRetrievePastMessagesLink = null;
}
 
if (_webSocketSharp != null)
{
_webSocketSharp.Close();
@@ -154,12 +275,14 @@
_initTask = RetrievePastMessages(_cancellationToken);
}
 
_runTask = Run(_cancellationToken);
_runTask = HeartBeat(_cancellationToken);
}
 
private void Connect()
{
_webSocketSharp = new WebSocket(_webSocketsUri.AbsoluteUri);
_webSocketSharp.EmitOnPing = true;
_webSocketSharp.WaitTime = TimeSpan.FromMinutes(1);
_webSocketSharp.SslConfiguration = new ClientSslConfiguration(_webSocketsUri.Host,
new X509CertificateCollection(new X509Certificate[] { }), SslProtocols.Tls12, false);
if (_configuration.Proxy.Enable)
@@ -195,8 +318,15 @@
private void WebSocketSharp_OnOpen(object sender, EventArgs e)
{
Log.Information($"WebSockets connection to server {_webSocketsUri.AbsoluteUri} is now open");
 
_webSocketsServerResponseScheduledContinuation.Schedule(TimeSpan.FromMinutes(1), OnUnresponsiveServer, _cancellationToken);
}
 
private void OnUnresponsiveServer()
{
Log.Warning($"Server {_server} has not responded in a long while...");
}
 
private async void WebSocketSharp_OnError(object sender, ErrorEventArgs e)
{
Log.Error(
@@ -210,6 +340,7 @@
}
 
await Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken);
 
Log.Information($"Reconnecting to websocket server {_webSocketsUri.AbsoluteUri}");
 
Connect();
@@ -217,64 +348,16 @@
 
private async void WebSocketSharp_OnMessage(object sender, MessageEventArgs e)
{
if (e.RawData.Length == 0)
if (e.IsPing)
{
Log.Warning("Empty message received from server");
return;
}
Log.Information($"Server {_server} sent PING message");
 
var message = Encoding.UTF8.GetString(e.RawData, 0, e.RawData.Length);
_webSocketsServerResponseScheduledContinuation.Schedule(TimeSpan.FromMinutes(1), OnUnresponsiveServer, _cancellationToken);
 
GotifyMessage gotifyNotification;
 
try
{
gotifyNotification = JsonConvert.DeserializeObject<GotifyMessage>(message);
}
catch (JsonSerializationException exception)
{
Log.Warning($"Could not deserialize notification: {exception.Message}");
return;
}
 
if (gotifyNotification == null)
{
Log.Warning($"Could not deserialize gotify notification: {message}");
 
return;
}
 
gotifyNotification.Server = _server;
 
var applicationUriBuilder = new UriBuilder(_httpUri);
try
{
applicationUriBuilder.Path = Path.Combine(applicationUriBuilder.Path, "application");
}
catch (ArgumentException exception)
{
Log.Warning("Could not build an URI to an application");
 
return;
}
 
using (var imageStream =
await RetrieveGotifyApplicationImage(gotifyNotification.AppId, applicationUriBuilder.Uri,
_cancellationToken))
{
if (imageStream == null)
{
Log.Warning("Could not find any application image for notification");
return;
}
 
var image = Image.FromStream(imageStream);
 
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(gotifyNotification, image));
}
 
Log.Debug($"Notification message received: {gotifyNotification.Message}");
await _webSocketMessageBufferBlock.SendAsync(e.RawData, _cancellationToken);
}
 
public void Stop()
@@ -291,7 +374,9 @@
private async Task RetrievePastMessages(CancellationToken cancellationToken)
{
var messageUriBuilder = new UriBuilder(_httpUri);
foreach (var application in await RetrieveGotifyApplications(cancellationToken))
 
var gotifyApplicationBufferBlock = new BufferBlock<GotifyApplication>(new DataflowBlockOptions { CancellationToken = cancellationToken });
var gotifyApplicationActionBlock = new ActionBlock<GotifyApplication>(async application =>
{
try
{
@@ -302,12 +387,22 @@
{
Log.Error($"No application URL could be built for {_server.Url} due to {exception.Message}");
 
continue;
return;
}
 
var messagesResponse = await _httpClient.GetAsync(messageUriBuilder.Uri, cancellationToken);
HttpResponseMessage messagesResponse;
try
{
messagesResponse = await _httpClient.GetAsync(messageUriBuilder.Uri, cancellationToken);
}
catch (Exception exception)
{
Log.Error($"Could not get application {application.Id} due to {exception.Message}");
 
return;
}
 
 
var messages = await messagesResponse.Content.ReadAsStringAsync();
 
GotifyMessageQuery gotifyMessageQuery;
@@ -320,54 +415,75 @@
{
Log.Warning($"Could not deserialize the message response: {exception.Message}");
 
continue;
return;
}
 
var applicationUriBuilder = new UriBuilder(_httpUri);
try
foreach (var message in gotifyMessageQuery.Messages.Where(message => message.Date >= DateTime.Now - TimeSpan.FromHours(_configuration.RetrievePastNotificationHours)))
{
applicationUriBuilder.Path = Path.Combine(applicationUriBuilder.Path, "application");
}
catch (ArgumentException exception)
{
Log.Warning($"Could not build an URI to an application: {exception}");
message.Server = _server;
 
return;
}
var cachedImage = _applicationImageCache.Get($"{message.AppId}");
if (cachedImage is Image applicationImage)
{
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(message, applicationImage));
return;
}
 
foreach (var message in gotifyMessageQuery.Messages)
{
if (message.Date < DateTime.Now - TimeSpan.FromHours(_configuration.RetrievePastNotificationHours))
using var imageStream = await RetrieveGotifyApplicationImage(message.AppId, _cancellationToken);
if (imageStream == null || imageStream.Length == 0)
{
Log.Warning("Could not find any application image for notification");
continue;
}
 
message.Server = _server;
var image = Image.FromStream(imageStream);
 
using (var imageStream =
await RetrieveGotifyApplicationImage(message.AppId, applicationUriBuilder.Uri,
_cancellationToken))
{
if (imageStream == null)
_applicationImageCache.Add($"{message.AppId}", image.Clone(),
new CacheItemPolicy
{
Log.Warning("Could not find any application image for notification");
return;
}
SlidingExpiration = TimeSpan.FromHours(1)
});
 
var image = Image.FromStream(imageStream);
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(message, image));
}
 
GotifyNotification?.Invoke(this,
new GotifyNotificationEventArgs(message, image));
}
}
}, new ExecutionDataflowBlockOptions { CancellationToken = cancellationToken });
 
gotifyApplicationBufferBlock.LinkTo(gotifyApplicationActionBlock,
new DataflowLinkOptions { PropagateCompletion = true });
 
await foreach (var application in RetrieveGotifyApplications(cancellationToken))
{
await gotifyApplicationBufferBlock.SendAsync(application, cancellationToken);
}
 
gotifyApplicationBufferBlock.Complete();
await gotifyApplicationActionBlock.Completion;
 
}
 
private async Task Run(CancellationToken cancellationToken)
private async Task HeartBeat(CancellationToken cancellationToken)
{
try
{
do
{
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
await Task.Delay(TimeSpan.FromMinutes(1), cancellationToken);
 
_webSocketsClientPingStopWatch.Restart();
if (!_webSocketSharp.Ping())
{
Log.Warning($"Server {_server} did not respond to PING message.");
continue;
}
 
var delta = _webSocketsClientPingStopWatch.ElapsedMilliseconds;
 
Log.Information($"PING response latency for {_server} is {delta}ms");
 
_webSocketsServerResponseScheduledContinuation.Schedule(TimeSpan.FromMinutes(1), OnUnresponsiveServer, _cancellationToken);
} while (!cancellationToken.IsCancellationRequested);
}
catch (Exception exception) when (exception is OperationCanceledException ||
@@ -376,11 +492,11 @@
}
catch (Exception exception)
{
Log.Warning(exception, "Failure running connection loop");
Log.Warning(exception, $"Heartbeat for server {_server} has failed due to {exception.Message}");
}
}
 
private async Task<GotifyApplication[]> RetrieveGotifyApplications(CancellationToken cancellationToken)
private async IAsyncEnumerable<GotifyApplication> RetrieveGotifyApplications([EnumeratorCancellation] CancellationToken cancellationToken)
{
var applicationsUriBuilder = new UriBuilder(_httpUri);
try
@@ -390,35 +506,25 @@
catch (ArgumentException exception)
{
Log.Error($"No application URL could be built for {_server.Url} due to {exception}");
 
yield break;
}
 
var applicationsResponse = await _httpClient.GetAsync(applicationsUriBuilder.Uri, cancellationToken);
HttpResponseMessage applicationsResponse;
 
var applications = await applicationsResponse.Content.ReadAsStringAsync();
 
GotifyApplication[] gotifyApplications;
try
{
gotifyApplications =
JsonConvert.DeserializeObject<GotifyApplication[]>(applications);
applicationsResponse = await _httpClient.GetAsync(applicationsUriBuilder.Uri, cancellationToken);
}
catch (JsonSerializationException exception)
catch (Exception exception)
{
Log.Warning($"Could not deserialize the list of applications from the server: {exception}");
Log.Error($"Could not retrieve applications: {exception.Message}");
 
return null;
yield break;
}
 
return gotifyApplications;
}
var applications = await applicationsResponse.Content.ReadAsStringAsync();
 
private async Task<Stream> RetrieveGotifyApplicationImage(int appId, Uri applicationUri,
CancellationToken cancellationToken)
{
var applicationResponse = await _httpClient.GetAsync(applicationUri, cancellationToken);
 
var applications = await applicationResponse.Content.ReadAsStringAsync();
 
GotifyApplication[] gotifyApplications;
try
{
@@ -427,32 +533,52 @@
}
catch (JsonSerializationException exception)
{
Log.Warning($"Could not deserialize the list of applications from the server: {exception.Message}");
Log.Warning($"Could not deserialize the list of applications from the server: {exception}");
 
return null;
yield break;
}
 
foreach (var application in gotifyApplications)
{
yield return application;
}
}
 
private async Task<Stream> RetrieveGotifyApplicationImage(int appId, CancellationToken cancellationToken)
{
await foreach (var application in RetrieveGotifyApplications(cancellationToken))
{
if (application.Id != appId) continue;
 
if (!Uri.TryCreate(Path.Combine($"{_httpUri}", $"{application.Image}"), UriKind.Absolute,
out var applicationImageUri))
if (!Uri.TryCreate(Path.Combine($"{_httpUri}", $"{application.Image}"), UriKind.Absolute, out var applicationImageUri))
{
Log.Warning("Could not build URL path to application icon");
continue;
}
 
var imageResponse = await _httpClient.GetAsync(applicationImageUri, cancellationToken);
HttpResponseMessage imageResponse;
 
try
{
imageResponse = await _httpClient.GetAsync(applicationImageUri, cancellationToken);
}
catch (Exception exception)
{
Log.Error($"Could not retrieve application image: {exception.Message}");
 
return new MemoryStream();
}
 
var memoryStream = new MemoryStream();
 
await imageResponse.Content.CopyToAsync(memoryStream);
 
memoryStream.Position = 0L;
 
return memoryStream;
}
 
return null;
return new MemoryStream();
}
 
#endregion
/trunk/Winify/Utilities/AES.cs
@@ -28,34 +28,26 @@
///////////////////////////////////////////////////////////////////////////
public static async Task<byte[]> Encrypt(byte[] plain, string password)
{
using (var rijndael = Rijndael.Create())
{
rijndael.BlockSize = 128;
rijndael.Mode = CipherMode.CBC;
rijndael.KeySize = 256;
rijndael.Padding = PaddingMode.PKCS7;
var salt = new byte[AESKeySaltBytes];
Rng.GetBytes(salt);
using (var pdb = new Rfc2898DeriveBytes(password, salt, 1000))
{
rijndael.Key = pdb.GetBytes(rijndael.KeySize / 8);
rijndael.IV = pdb.GetBytes(rijndael.BlockSize / 8);
using var rijndael = Rijndael.Create();
rijndael.BlockSize = 128;
rijndael.Mode = CipherMode.CBC;
rijndael.KeySize = 256;
rijndael.Padding = PaddingMode.PKCS7;
var salt = new byte[AESKeySaltBytes];
Rng.GetBytes(salt);
using var pdb = new Rfc2898DeriveBytes(password, salt, 1000);
rijndael.Key = pdb.GetBytes(rijndael.KeySize / 8);
rijndael.IV = pdb.GetBytes(rijndael.BlockSize / 8);
 
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream =
new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
{
await cryptoStream.WriteAsync(plain, 0, plain.Length);
cryptoStream.Close();
using var memoryStream = new MemoryStream();
using var cryptoStream =
new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
await cryptoStream.WriteAsync(plain, 0, plain.Length);
cryptoStream.Close();
 
var ciphertext = memoryStream.ToArray();
var ciphertext = memoryStream.ToArray();
 
return salt.Concat(ciphertext).ToArray();
}
}
}
}
return salt.Concat(ciphertext).ToArray();
}
 
///////////////////////////////////////////////////////////////////////////
@@ -63,35 +55,27 @@
///////////////////////////////////////////////////////////////////////////
public static async Task<byte[]> Decrypt(byte[] cipher, string password)
{
using (var rijndael = Rijndael.Create())
{
rijndael.BlockSize = 128;
rijndael.Mode = CipherMode.CBC;
rijndael.KeySize = 256;
rijndael.Padding = PaddingMode.PKCS7;
using var rijndael = Rijndael.Create();
rijndael.BlockSize = 128;
rijndael.Mode = CipherMode.CBC;
rijndael.KeySize = 256;
rijndael.Padding = PaddingMode.PKCS7;
 
var salt = cipher.Take(AESKeySaltBytes).ToArray();
var salt = cipher.Take(AESKeySaltBytes).ToArray();
 
var ciphertext = cipher.Skip(AESKeySaltBytes).ToArray();
var ciphertext = cipher.Skip(AESKeySaltBytes).ToArray();
 
using (var pdb = new Rfc2898DeriveBytes(password, salt, 1000))
{
rijndael.Key = pdb.GetBytes(rijndael.KeySize / 8);
rijndael.IV = pdb.GetBytes(rijndael.BlockSize / 8);
using var pdb = new Rfc2898DeriveBytes(password, salt, 1000);
rijndael.Key = pdb.GetBytes(rijndael.KeySize / 8);
rijndael.IV = pdb.GetBytes(rijndael.BlockSize / 8);
 
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream =
new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write))
{
await cryptoStream.WriteAsync(ciphertext, 0, ciphertext.Length);
cryptoStream.Close();
using var memoryStream = new MemoryStream();
using var cryptoStream =
new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);
await cryptoStream.WriteAsync(ciphertext, 0, ciphertext.Length);
cryptoStream.Close();
 
return memoryStream.ToArray();
}
}
}
}
return memoryStream.ToArray();
}
 
#endregion
/trunk/Winify/Utilities/LogMemorySink.cs
@@ -20,11 +20,9 @@
{
if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
 
using (var stringWriter = new StringWriter())
{
_textFormatter.Format(logEvent, stringWriter);
Events.Add(stringWriter.ToString());
}
using var stringWriter = new StringWriter();
_textFormatter.Format(logEvent, stringWriter);
Events.Add(stringWriter.ToString());
}
 
public void Clear()
/trunk/Winify/Utilities/Miscellaneous.cs
@@ -17,32 +17,28 @@
 
public static bool LaunchOnBootSet(bool enable)
{
using (var key = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
using var key = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
if (key == null) return false;
 
switch (enable)
{
if (key == null) return false;
case true:
key.SetValue(Constants.AssemblyName, Assembly.GetEntryAssembly().Location);
break;
default:
key.DeleteValue(Constants.AssemblyName, false);
break;
}
 
switch (enable)
{
case true:
key.SetValue(Constants.AssemblyName, Assembly.GetEntryAssembly().Location);
break;
default:
key.DeleteValue(Constants.AssemblyName, false);
break;
}
 
return true;
}
return true;
}
 
public static bool LaunchOnBootGet()
{
using (var key = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
return key?.GetValue(Constants.AssemblyName) != null;
}
using var key = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
return key?.GetValue(Constants.AssemblyName) != null;
}
 
/// <summary>
@@ -66,13 +62,11 @@
public static async Task<Icon> CreateIconFromResource(string resource)
{
var iconBytes = await LoadResource(resource);
using (var iconMemoryStream = new MemoryStream(iconBytes))
{
var bitmap = (Bitmap)Image.FromStream(iconMemoryStream);
var bitmapIntPtr = bitmap.GetHicon();
var icon = Icon.FromHandle(bitmapIntPtr);
return icon;
}
using var iconMemoryStream = new MemoryStream(iconBytes);
var bitmap = (Bitmap)Image.FromStream(iconMemoryStream);
var bitmapIntPtr = bitmap.GetHicon();
var icon = Icon.FromHandle(bitmapIntPtr);
return icon;
}
 
public static async Task<byte[]> LoadResource(string resource)
@@ -79,18 +73,16 @@
{
var assembly = Assembly.GetExecutingAssembly();
 
using (var manifestResourceStream = assembly.GetManifestResourceStream(resource))
{
if (manifestResourceStream == null) return null;
using var manifestResourceStream = assembly.GetManifestResourceStream(resource);
if (manifestResourceStream == null) return null;
 
var memoryStream = new MemoryStream();
var memoryStream = new MemoryStream();
 
await manifestResourceStream.CopyToAsync(memoryStream);
await manifestResourceStream.CopyToAsync(memoryStream);
 
memoryStream.Position = 0L;
memoryStream.Position = 0L;
 
return memoryStream.ToArray();
}
return memoryStream.ToArray();
}
 
public static void InvokeIfRequired<T>(this T control, Action<T> action) where T : Control
@@ -150,23 +142,19 @@
var location = @"SOFTWARE\Microsoft\Cryptography";
var name = "MachineGuid";
 
using (var localMachineX64View =
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var rk = localMachineX64View.OpenSubKey(location))
{
if (rk == null)
throw new KeyNotFoundException(
string.Format("Key Not Found: {0}", location));
using var localMachineX64View =
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
using var rk = localMachineX64View.OpenSubKey(location);
if (rk == null)
throw new KeyNotFoundException(
string.Format("Key Not Found: {0}", location));
 
var machineGuid = rk.GetValue(name);
if (machineGuid == null)
throw new IndexOutOfRangeException(
string.Format("Index Not Found: {0}", name));
var machineGuid = rk.GetValue(name);
if (machineGuid == null)
throw new IndexOutOfRangeException(
string.Format("Index Not Found: {0}", name));
 
return machineGuid.ToString();
}
}
return machineGuid.ToString();
}
 
#endregion
/trunk/Winify/Utilities/Serialization/Serialization.cs
@@ -49,28 +49,24 @@
 
settings.Schemas.Add(targetNamespace, schemeUri);
 
using (var fileStream =
await Miscellaneous.GetFileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read,
cancellationToken))
using var fileStream =
await Miscellaneous.GetFileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read,
cancellationToken);
using var xmlReader = XmlReader.Create(fileStream,
settings);
var stringBuilder = new StringBuilder();
 
using (var stringWriter = new StringWriter(stringBuilder))
{
using (var xmlReader = XmlReader.Create(fileStream,
settings))
{
var stringBuilder = new StringBuilder();
while (await xmlReader.ReadAsync())
await stringWriter.WriteAsync(await xmlReader.ReadOuterXmlAsync());
}
 
using (var stringWriter = new StringWriter(stringBuilder))
{
while (await xmlReader.ReadAsync())
await stringWriter.WriteAsync(await xmlReader.ReadOuterXmlAsync());
}
 
using (var stringReader = new StringReader(stringBuilder.ToString()))
{
servers =
(T)xmlSerializer
.Deserialize(stringReader);
}
}
using (var stringReader = new StringReader(stringBuilder.ToString()))
{
servers =
(T)xmlSerializer
.Deserialize(stringReader);
}
}
catch (Exception exception)
@@ -93,36 +89,30 @@
 
try
{
using (var memoryStream = new MemoryStream())
{
using (var xmlWriter =
XmlWriter.Create(memoryStream,
new XmlWriterSettings
{
Async = true,
Indent = true,
IndentChars = " ",
OmitXmlDeclaration = false
}))
{
await xmlWriter.WriteDocTypeAsync(name,
null,
null,
subset);
using var memoryStream = new MemoryStream();
using var xmlWriter =
XmlWriter.Create(memoryStream,
new XmlWriterSettings
{
Async = true,
Indent = true,
IndentChars = " ",
OmitXmlDeclaration = false
});
await xmlWriter.WriteDocTypeAsync(name,
null,
null,
subset);
 
xmlSerializer.Serialize(xmlWriter, servers);
xmlSerializer.Serialize(xmlWriter, servers);
 
using (var fileStream =
await Miscellaneous.GetFileStream(file, FileMode.Create, FileAccess.Write,
FileShare.Write,
cancellationToken))
{
memoryStream.Position = 0L;
using var fileStream =
await Miscellaneous.GetFileStream(file, FileMode.Create, FileAccess.Write,
FileShare.Write,
cancellationToken);
memoryStream.Position = 0L;
 
await memoryStream.CopyToAsync(fileStream);
}
}
}
await memoryStream.CopyToAsync(fileStream);
}
catch (Exception exception)
{
/trunk/Winify/Winify.csproj
@@ -38,7 +38,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>7.3</LangVersion>
<LangVersion>8</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -48,7 +48,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>7.3</LangVersion>
<LangVersion>8</LangVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Winify.ico</ApplicationIcon>
@@ -63,6 +63,9 @@
<Reference Include="Jot, Version=2.1.17.0, Culture=neutral, PublicKeyToken=6b498f69c5f88322, processorArchitecture=MSIL">
<HintPath>..\packages\Jot.2.1.17\lib\netstandard2.0\Jot.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="NetSparkle, Version=2.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NetSparkleUpdater.SparkleUpdater.2.2.3\lib\net452\NetSparkle.dll</HintPath>
</Reference>
@@ -100,6 +103,10 @@
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
<Private>True</Private>
@@ -120,6 +127,12 @@
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Tasks.Dataflow, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Dataflow.7.0.0\lib\net462\System.Threading.Tasks.Dataflow.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Windows" />
<Reference Include="System.Xaml" />
<Reference Include="Microsoft.CSharp" />
/trunk/Winify/packages.config
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Jot" version="2.1.17" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="7.0.0" targetFramework="net48" />
<package id="NetSparkleUpdater.SparkleUpdater" version="2.2.3" targetFramework="net472" />
<package id="NetSparkleUpdater.UI.WinForms.NetFramework" version="2.2.3" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
@@ -10,9 +11,12 @@
<package id="System.IO" version="4.3.0" targetFramework="net472" />
<package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
<package id="System.Runtime" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net48" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Tasks.Dataflow" version="7.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
<package id="WebSocketSharp" version="1.0.3-rc11" targetFramework="net472" />
</packages>