mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Bring back C# sample logging!
This commit is contained in:
@@ -4,6 +4,7 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Velopack;
|
using Velopack;
|
||||||
|
using Velopack.Logging;
|
||||||
|
|
||||||
namespace CSharpAvalonia;
|
namespace CSharpAvalonia;
|
||||||
|
|
||||||
@@ -19,6 +20,8 @@ public partial class MainWindow : Window
|
|||||||
var updateUrl = SampleHelper.GetReleasesDir(); // replace with your update path/url
|
var updateUrl = SampleHelper.GetReleasesDir(); // replace with your update path/url
|
||||||
_um = new UpdateManager(updateUrl);
|
_um = new UpdateManager(updateUrl);
|
||||||
|
|
||||||
|
TextLog.Text = Program.Log.ToString();
|
||||||
|
Program.Log.LogUpdated += LogUpdated;
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +32,7 @@ public partial class MainWindow : Window
|
|||||||
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
||||||
_update = await _um.CheckForUpdatesAsync().ConfigureAwait(true);
|
_update = await _um.CheckForUpdatesAsync().ConfigureAwait(true);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogMessage("Error checking for updates", ex);
|
Program.Log.LogError(ex, "Error checking for updates");
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
@@ -42,7 +45,7 @@ public partial class MainWindow : Window
|
|||||||
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
||||||
await _um.DownloadUpdatesAsync(_update, Progress).ConfigureAwait(true);
|
await _um.DownloadUpdatesAsync(_update, Progress).ConfigureAwait(true);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogMessage("Error downloading updates", ex);
|
Program.Log.LogError(ex, "Error downloading updates");
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
@@ -53,16 +56,12 @@ public partial class MainWindow : Window
|
|||||||
_um.ApplyUpdatesAndRestart(_update);
|
_um.ApplyUpdatesAndRestart(_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogMessage(string text, Exception e = null)
|
private void LogUpdated(object sender, LogUpdatedEventArgs e)
|
||||||
{
|
{
|
||||||
// logs can be sent from other threads
|
// logs can be sent from other threads
|
||||||
Dispatcher.UIThread.InvokeAsync(
|
Dispatcher.UIThread.InvokeAsync(
|
||||||
() => {
|
() => {
|
||||||
TextLog.Text += text + Environment.NewLine;
|
TextLog.Text = e.Text;
|
||||||
if (e != null) {
|
|
||||||
TextLog.Text += e.ToString() + Environment.NewLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollLog.ScrollToEnd();
|
ScrollLog.ScrollToEnd();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -78,7 +77,7 @@ public partial class MainWindow : Window
|
|||||||
|
|
||||||
private void Working()
|
private void Working()
|
||||||
{
|
{
|
||||||
LogMessage("");
|
Program.Log.LogInformation("");
|
||||||
BtnCheckUpdate.IsEnabled = false;
|
BtnCheckUpdate.IsEnabled = false;
|
||||||
BtnDownloadUpdate.IsEnabled = false;
|
BtnDownloadUpdate.IsEnabled = false;
|
||||||
BtnRestartApply.IsEnabled = false;
|
BtnRestartApply.IsEnabled = false;
|
||||||
|
|||||||
39
samples/CSharpAvalonia/MemoryLogger.cs
Normal file
39
samples/CSharpAvalonia/MemoryLogger.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using Velopack.Logging;
|
||||||
|
|
||||||
|
namespace CSharpAvalonia;
|
||||||
|
|
||||||
|
public class LogUpdatedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string Text { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MemoryLogger : IVelopackLogger
|
||||||
|
{
|
||||||
|
public event EventHandler<LogUpdatedEventArgs> LogUpdated;
|
||||||
|
private readonly StringBuilder _sb = new StringBuilder();
|
||||||
|
|
||||||
|
public IDisposable BeginScope<TState>(TState state)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
lock (_sb) {
|
||||||
|
return _sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(VelopackLogLevel logLevel, string message, Exception exception)
|
||||||
|
{
|
||||||
|
lock (_sb) {
|
||||||
|
message = $"{logLevel}: {message}";
|
||||||
|
if (exception != null) message += "\n" + exception.ToString();
|
||||||
|
Console.WriteLine("log: " + message);
|
||||||
|
_sb.AppendLine(message);
|
||||||
|
LogUpdated?.Invoke(this, new LogUpdatedEventArgs { Text = _sb.ToString() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ namespace CSharpAvalonia;
|
|||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
|
public static MemoryLogger Log { get; private set; } = new();
|
||||||
|
|
||||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||||
// yet and stuff might break.
|
// yet and stuff might break.
|
||||||
@@ -16,6 +18,7 @@ class Program
|
|||||||
// It's important to Run() the VelopackApp as early as possible in app startup.
|
// It's important to Run() the VelopackApp as early as possible in app startup.
|
||||||
VelopackApp.Build()
|
VelopackApp.Build()
|
||||||
.OnFirstRun((v) => { /* Your first run code here */ })
|
.OnFirstRun((v) => { /* Your first run code here */ })
|
||||||
|
.SetLogger(Log)
|
||||||
.Run();
|
.Run();
|
||||||
|
|
||||||
// Now it's time to run Avalonia
|
// Now it's time to run Avalonia
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ namespace CSharpWpf
|
|||||||
{
|
{
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
public static MemoryLogger Log { get; private set; } = new();
|
||||||
|
|
||||||
// Since WPF has an "automatic" Program.Main, we need to create our own.
|
// Since WPF has an "automatic" Program.Main, we need to create our own.
|
||||||
// In order for this to work, you must also add the following to your .csproj:
|
// In order for this to work, you must also add the following to your .csproj:
|
||||||
// <StartupObject>CSharpWpf.App</StartupObject>
|
// <StartupObject>CSharpWpf.App</StartupObject>
|
||||||
@@ -15,6 +17,7 @@ namespace CSharpWpf
|
|||||||
// It's important to Run() the VelopackApp as early as possible in app startup.
|
// It's important to Run() the VelopackApp as early as possible in app startup.
|
||||||
VelopackApp.Build()
|
VelopackApp.Build()
|
||||||
.OnFirstRun((v) => { /* Your first run code here */ })
|
.OnFirstRun((v) => { /* Your first run code here */ })
|
||||||
|
.SetLogger(Log)
|
||||||
.Run();
|
.Run();
|
||||||
|
|
||||||
// We can now launch the WPF application as normal.
|
// We can now launch the WPF application as normal.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Velopack;
|
using Velopack;
|
||||||
|
using Velopack.Logging;
|
||||||
|
|
||||||
namespace CSharpWpf
|
namespace CSharpWpf
|
||||||
{
|
{
|
||||||
@@ -16,6 +17,8 @@ namespace CSharpWpf
|
|||||||
string updateUrl = SampleHelper.GetReleasesDir(); // replace with your update url
|
string updateUrl = SampleHelper.GetReleasesDir(); // replace with your update url
|
||||||
_um = new UpdateManager(updateUrl);
|
_um = new UpdateManager(updateUrl);
|
||||||
|
|
||||||
|
TextLog.Text = App.Log.ToString();
|
||||||
|
App.Log.LogUpdated += LogUpdated;
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +29,7 @@ namespace CSharpWpf
|
|||||||
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
||||||
_update = await _um.CheckForUpdatesAsync().ConfigureAwait(true);
|
_update = await _um.CheckForUpdatesAsync().ConfigureAwait(true);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogMessage("Error checking for updates", ex);
|
App.Log.LogError(ex, "Error checking for updates");
|
||||||
}
|
}
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
@@ -38,7 +41,7 @@ namespace CSharpWpf
|
|||||||
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
// ConfigureAwait(true) so that UpdateStatus() is called on the UI thread
|
||||||
await _um.DownloadUpdatesAsync(_update, Progress).ConfigureAwait(true);
|
await _um.DownloadUpdatesAsync(_update, Progress).ConfigureAwait(true);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogMessage("Error downloading updates", ex);
|
App.Log.LogError(ex, "Error downloading updates");
|
||||||
}
|
}
|
||||||
UpdateStatus();
|
UpdateStatus();
|
||||||
}
|
}
|
||||||
@@ -48,14 +51,11 @@ namespace CSharpWpf
|
|||||||
_um.ApplyUpdatesAndRestart(_update);
|
_um.ApplyUpdatesAndRestart(_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogMessage(string text, Exception e = null)
|
private void LogUpdated(object sender, LogUpdatedEventArgs e)
|
||||||
{
|
{
|
||||||
// logs can be sent from other threads
|
// logs can be sent from other threads
|
||||||
this.Dispatcher.InvokeAsync(() => {
|
this.Dispatcher.InvokeAsync(() => {
|
||||||
TextLog.Text += text + Environment.NewLine;
|
TextLog.Text = e.Text;
|
||||||
if (e != null) {
|
|
||||||
TextLog.Text += e.ToString() + Environment.NewLine;
|
|
||||||
}
|
|
||||||
ScrollLog.ScrollToEnd();
|
ScrollLog.ScrollToEnd();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ namespace CSharpWpf
|
|||||||
|
|
||||||
private void Working()
|
private void Working()
|
||||||
{
|
{
|
||||||
LogMessage("");
|
App.Log.LogInformation("");
|
||||||
BtnCheckUpdate.IsEnabled = false;
|
BtnCheckUpdate.IsEnabled = false;
|
||||||
BtnDownloadUpdate.IsEnabled = false;
|
BtnDownloadUpdate.IsEnabled = false;
|
||||||
BtnRestartApply.IsEnabled = false;
|
BtnRestartApply.IsEnabled = false;
|
||||||
|
|||||||
39
samples/CSharpWpf/MemoryLogger.cs
Normal file
39
samples/CSharpWpf/MemoryLogger.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using Velopack.Logging;
|
||||||
|
|
||||||
|
namespace CSharpWpf;
|
||||||
|
|
||||||
|
public class LogUpdatedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string Text { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MemoryLogger : IVelopackLogger
|
||||||
|
{
|
||||||
|
public event EventHandler<LogUpdatedEventArgs> LogUpdated;
|
||||||
|
private readonly StringBuilder _sb = new StringBuilder();
|
||||||
|
|
||||||
|
public IDisposable BeginScope<TState>(TState state)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
lock (_sb) {
|
||||||
|
return _sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(VelopackLogLevel logLevel, string message, Exception exception)
|
||||||
|
{
|
||||||
|
lock (_sb) {
|
||||||
|
message = $"{logLevel}: {message}";
|
||||||
|
if (exception != null) message += "\n" + exception.ToString();
|
||||||
|
Console.WriteLine("log: " + message);
|
||||||
|
_sb.AppendLine(message);
|
||||||
|
LogUpdated?.Invoke(this, new LogUpdatedEventArgs { Text = _sb.ToString() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ namespace Velopack
|
|||||||
private string[]? _args;
|
private string[]? _args;
|
||||||
private bool _autoApply = true;
|
private bool _autoApply = true;
|
||||||
private IVelopackLocator? _customLocator;
|
private IVelopackLocator? _customLocator;
|
||||||
|
private IVelopackLogger? _customLogger;
|
||||||
|
|
||||||
private VelopackApp()
|
private VelopackApp()
|
||||||
{
|
{
|
||||||
@@ -74,6 +75,17 @@ namespace Velopack
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a custom logger to the Velopack application. This will be used for all Velopack diagnostic
|
||||||
|
/// messages in addition to the default log file location. This will be cached and re-used throughout
|
||||||
|
/// the lifetime of the application. If you have also provided a custom locator, this logger will be ignored.
|
||||||
|
/// </summary>
|
||||||
|
public VelopackApp SetLogger(IVelopackLogger logger)
|
||||||
|
{
|
||||||
|
_customLogger = logger;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This hook is triggered when the application is started for the first time after installation.
|
/// This hook is triggered when the application is started for the first time after installation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -151,13 +163,6 @@ namespace Velopack
|
|||||||
{
|
{
|
||||||
var args = _args ?? Environment.GetCommandLineArgs().Skip(1).ToArray();
|
var args = _args ?? Environment.GetCommandLineArgs().Skip(1).ToArray();
|
||||||
|
|
||||||
// internal hook run by the Velopack tooling to check everything is working
|
|
||||||
if (args.Length >= 1 && args[0].Equals("--veloapp-version", StringComparison.OrdinalIgnoreCase)) {
|
|
||||||
Console.WriteLine(VelopackRuntimeInfo.VelopackNugetVersion);
|
|
||||||
Exit(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VelopackLocator.IsCurrentSet) {
|
if (VelopackLocator.IsCurrentSet) {
|
||||||
VelopackLocator.Current.Log.Error(
|
VelopackLocator.Current.Log.Error(
|
||||||
"VelopackApp.Build().Run() was called more than once. This is not allowed and can lead to unexpected behaviour.");
|
"VelopackApp.Build().Run() was called more than once. This is not allowed and can lead to unexpected behaviour.");
|
||||||
@@ -167,7 +172,7 @@ namespace Velopack
|
|||||||
VelopackLocator.SetCurrentLocator(_customLocator);
|
VelopackLocator.SetCurrentLocator(_customLocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
var locator = VelopackLocator.GetCurrentOrCreateDefault();
|
var locator = VelopackLocator.GetCurrentOrCreateDefault(_customLogger);
|
||||||
var log = locator.Log;
|
var log = locator.Log;
|
||||||
|
|
||||||
log.Info($"Starting VelopackApp.Run (library version {VelopackRuntimeInfo.VelopackNugetVersion}).");
|
log.Info($"Starting VelopackApp.Run (library version {VelopackRuntimeInfo.VelopackNugetVersion}).");
|
||||||
|
|||||||
Reference in New Issue
Block a user