diff --git a/Directory.Build.props b/Directory.Build.props
index 932b68ade..080b20f88 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,16 +1,19 @@
-
- none
- false
-
9.0
enable
false
-
+
+
+ SIGN_ASSEMBLY;$(DefineConstants)
true
false
..\Unicorn.pfx
+
+
+ none
+ false
+
\ No newline at end of file
diff --git a/Packager/Form1.Designer.cs b/Packager/Form1.Designer.cs
new file mode 100644
index 000000000..0b7e39a27
--- /dev/null
+++ b/Packager/Form1.Designer.cs
@@ -0,0 +1,123 @@
+
+namespace Packager
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.button1 = new System.Windows.Forms.Button();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
+ this.button2 = new System.Windows.Forms.Button();
+ this.richTextBox1 = new System.Windows.Forms.RichTextBox();
+ this.button3 = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(12, 12);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(64, 72);
+ this.button1.TabIndex = 0;
+ this.button1.Text = "Select Folder";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.OnBtnSelectPathClick);
+ //
+ // textBox1
+ //
+ this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBox1.Location = new System.Drawing.Point(82, 12);
+ this.textBox1.Multiline = true;
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(706, 72);
+ this.textBox1.TabIndex = 1;
+ //
+ // openFileDialog1
+ //
+ this.openFileDialog1.FileName = "openFileDialog1";
+ //
+ // button2
+ //
+ this.button2.Location = new System.Drawing.Point(12, 90);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(64, 72);
+ this.button2.TabIndex = 2;
+ this.button2.Text = "Create";
+ this.button2.UseVisualStyleBackColor = true;
+ this.button2.Click += new System.EventHandler(this.OnBtnCreateClick);
+ //
+ // richTextBox1
+ //
+ this.richTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.richTextBox1.Location = new System.Drawing.Point(82, 90);
+ this.richTextBox1.Name = "richTextBox1";
+ this.richTextBox1.Size = new System.Drawing.Size(706, 348);
+ this.richTextBox1.TabIndex = 3;
+ this.richTextBox1.Text = "";
+ //
+ // button3
+ //
+ this.button3.Location = new System.Drawing.Point(12, 168);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(64, 72);
+ this.button3.TabIndex = 4;
+ this.button3.Text = "Unpack";
+ this.button3.UseVisualStyleBackColor = true;
+ this.button3.Click += new System.EventHandler(this.OnBtnUnpackClick);
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(800, 450);
+ this.Controls.Add(this.button3);
+ this.Controls.Add(this.richTextBox1);
+ this.Controls.Add(this.button2);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.button1);
+ this.Name = "Form1";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Packager";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.OpenFileDialog openFileDialog1;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.RichTextBox richTextBox1;
+ private System.Windows.Forms.Button button3;
+ }
+}
+
diff --git a/Packager/Form1.cs b/Packager/Form1.cs
new file mode 100644
index 000000000..861d9d0e5
--- /dev/null
+++ b/Packager/Form1.cs
@@ -0,0 +1,180 @@
+using ICSharpCode.SharpZipLib.Tar;
+using System;
+using System.Application;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Packager
+{
+ public partial class Form1 : Form
+ {
+ readonly string app_path = @"\System.Application.SteamTools.Client.Desktop.Avalonia.App\bin\Release\Publish\win-x64";
+
+ static string GetPath(string path)
+ {
+ if (Path.DirectorySeparatorChar == '\\') return path;
+ return path.Replace('\\', Path.DirectorySeparatorChar);
+ }
+
+ public Form1()
+ {
+ InitializeComponent();
+ textBox1.Text = GetPath(GetProjectPath() + app_path);
+ }
+
+ static string GetProjectPath(string? path = null)
+ {
+ path ??= AppContext.BaseDirectory;
+ if (!Directory.GetFiles(path, "*.sln").Any())
+ {
+ var parent = Directory.GetParent(path);
+ if (parent == null) return string.Empty;
+ return GetProjectPath(parent.FullName);
+ }
+ return path;
+ }
+
+ void OnBtnSelectPathClick(object sender, EventArgs e)
+ {
+ if (openFileDialog1.ShowDialog() == DialogResult.OK)
+ {
+ textBox1.Text = Path.GetDirectoryName(openFileDialog1.FileName);
+ }
+ }
+
+ string? filePath = null;
+
+ private void OnBtnCreateClick(object sender, EventArgs e)
+ {
+ var dirPath = textBox1.Text;
+ var parent = Directory.GetParent(dirPath)?.FullName;
+ if (parent != null)
+ {
+ filePath = Path.Combine(parent, DateTime.Now.ToString("yyyyMMddHHmmssfffffff")) + FileEx.TAR_GZ;
+ TarGZipHelper.Create(filePath, dirPath, progress: ShowTarProgressMessage);
+ }
+ else
+ {
+ richTextBox1.AppendText("Fail, Parent is null");
+ richTextBox1.AppendText(Environment.NewLine);
+ }
+ }
+
+ void ShowTarProgressMessage(TarArchive archive, TarEntry entry, string message)
+ {
+ if (entry.TarHeader.TypeFlag != TarHeader.LF_NORMAL && entry.TarHeader.TypeFlag != TarHeader.LF_OLDNORM)
+ {
+ richTextBox1.AppendText("Entry type " + (char)entry.TarHeader.TypeFlag + " found!");
+ richTextBox1.AppendText(Environment.NewLine);
+ }
+ richTextBox1.AppendText(entry.Name + " " + message);
+ richTextBox1.AppendText(Environment.NewLine);
+ string modeString = DecodeType(entry.TarHeader.TypeFlag, entry.Name.EndsWith("/")) + DecodeMode(entry.TarHeader.Mode);
+ string userString = (string.IsNullOrEmpty(entry.UserName)) ? entry.UserId.ToString() : entry.UserName;
+ string groupString = (string.IsNullOrEmpty(entry.GroupName)) ? entry.GroupId.ToString() : entry.GroupName;
+ richTextBox1.AppendText(string.Format("{0} {1}/{2} {3,8} {4:yyyy-MM-dd HH:mm:ss}", modeString, userString, groupString, entry.Size, entry.ModTime.ToLocalTime()));
+ richTextBox1.AppendText(Environment.NewLine);
+ }
+
+ static string DecodeType(int type, bool slashTerminated)
+ {
+ string result = "?";
+ switch (type)
+ {
+ case TarHeader.LF_OLDNORM: // -jr- TODO this decoding is incomplete, not all possible known values are decoded...
+ case TarHeader.LF_NORMAL:
+ case TarHeader.LF_LINK:
+ if (slashTerminated)
+ result = "d";
+ else
+ result = "-";
+ break;
+
+ case TarHeader.LF_DIR:
+ result = "d";
+ break;
+
+ case TarHeader.LF_GNU_VOLHDR:
+ result = "V";
+ break;
+
+ case TarHeader.LF_GNU_MULTIVOL:
+ result = "M";
+ break;
+
+ case TarHeader.LF_CONTIG:
+ result = "C";
+ break;
+
+ case TarHeader.LF_FIFO:
+ result = "p";
+ break;
+
+ case TarHeader.LF_SYMLINK:
+ result = "l";
+ break;
+
+ case TarHeader.LF_CHR:
+ result = "c";
+ break;
+
+ case TarHeader.LF_BLK:
+ result = "b";
+ break;
+ }
+
+ return result;
+ }
+
+ static string DecodeMode(int mode)
+ {
+
+ const int S_ISUID = 0x0800;
+ const int S_ISGID = 0x0400;
+ const int S_ISVTX = 0x0200;
+
+ const int S_IRUSR = 0x0100;
+ const int S_IWUSR = 0x0080;
+ const int S_IXUSR = 0x0040;
+
+ const int S_IRGRP = 0x0020;
+ const int S_IWGRP = 0x0010;
+ const int S_IXGRP = 0x0008;
+
+ const int S_IROTH = 0x0004;
+ const int S_IWOTH = 0x0002;
+ const int S_IXOTH = 0x0001;
+
+
+ var result = new System.Text.StringBuilder();
+ result.Append((mode & S_IRUSR) != 0 ? 'r' : '-');
+ result.Append((mode & S_IWUSR) != 0 ? 'w' : '-');
+ result.Append((mode & S_ISUID) != 0
+ ? ((mode & S_IXUSR) != 0 ? 's' : 'S')
+ : ((mode & S_IXUSR) != 0 ? 'x' : '-'));
+ result.Append((mode & S_IRGRP) != 0 ? 'r' : '-');
+ result.Append((mode & S_IWGRP) != 0 ? 'w' : '-');
+ result.Append((mode & S_ISGID) != 0
+ ? ((mode & S_IXGRP) != 0 ? 's' : 'S')
+ : ((mode & S_IXGRP) != 0 ? 'x' : '-'));
+ result.Append((mode & S_IROTH) != 0 ? 'r' : '-');
+ result.Append((mode & S_IWOTH) != 0 ? 'w' : '-');
+ result.Append((mode & S_ISVTX) != 0
+ ? ((mode & S_IXOTH) != 0 ? 't' : 'T')
+ : ((mode & S_IXOTH) != 0 ? 'x' : '-'));
+
+ return result.ToString();
+ }
+
+ private void OnBtnUnpackClick(object sender, EventArgs e)
+ {
+ if (filePath != null)
+ {
+ var dirName = Path.GetFileName(filePath).Split('.').First();
+ TarGZipHelper.Unpack(filePath,
+ Path.Combine(Path.GetDirectoryName(filePath).ThrowIsNull(nameof(filePath)), dirName), ShowTarProgressMessage);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Packager/Form1.resx b/Packager/Form1.resx
new file mode 100644
index 000000000..f298a7be8
--- /dev/null
+++ b/Packager/Form1.resx
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Packager/Packager.csproj b/Packager/Packager.csproj
new file mode 100644
index 000000000..beeff6c71
--- /dev/null
+++ b/Packager/Packager.csproj
@@ -0,0 +1,35 @@
+
+
+
+ WinExe
+ net5.0-windows
+ true
+ ..\System.Application.SteamTools.Client.Desktop.Avalonia.App\Assets\Icon.ico
+
+
+
+
+ Properties\AssemblyInfo.cs
+
+
+ Properties\ThisAssembly.cs
+
+
+ Utils\TarGZipHelper.cs
+
+
+ Utils\ObjectExtensions.cs
+
+
+ Utils\StringExtensions.Trim.cs
+
+
+ Utils\FileEx.cs
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Packager/Program.cs b/Packager/Program.cs
new file mode 100644
index 000000000..72c4c6340
--- /dev/null
+++ b/Packager/Program.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Packager
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.SetHighDpiMode(HighDpiMode.SystemAware);
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/SteamToolsV1.2+.sln b/SteamToolsV1.2+.sln
index 8936e4ab2..736ef08a0 100644
--- a/SteamToolsV1.2+.sln
+++ b/SteamToolsV1.2+.sln
@@ -67,6 +67,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Application.SteamToo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Win7Troubleshoot", "Win7Troubleshoot\Win7Troubleshoot.csproj", "{60530AF8-4790-4A85-BCE2-C5673E9C601B}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Packager", "Packager\Packager.csproj", "{5A539932-2EB9-40F6-A4C1-94E5ECAB3B34}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -155,6 +157,10 @@ Global
{60530AF8-4790-4A85-BCE2-C5673E9C601B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60530AF8-4790-4A85-BCE2-C5673E9C601B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60530AF8-4790-4A85-BCE2-C5673E9C601B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5A539932-2EB9-40F6-A4C1-94E5ECAB3B34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A539932-2EB9-40F6-A4C1-94E5ECAB3B34}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A539932-2EB9-40F6-A4C1-94E5ECAB3B34}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A539932-2EB9-40F6-A4C1-94E5ECAB3B34}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -186,6 +192,7 @@ Global
{948C1EA8-12DB-4F8A-A190-8615DFBD9FE4} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{141532E1-540E-4E50-8723-96936C191281} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{60530AF8-4790-4A85-BCE2-C5673E9C601B} = {1460800B-D9ED-4147-B1E7-ABF502BEF59A}
+ {5A539932-2EB9-40F6-A4C1-94E5ECAB3B34} = {1460800B-D9ED-4147-B1E7-ABF502BEF59A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3833E7C5-69BC-4CB3-92CE-A8854AA35D8A}
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs
index d269ceda5..19b8f9151 100644
--- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs
@@ -4,6 +4,7 @@ using Avalonia.Markup.Xaml;
using System.Application.UI.ViewModels;
using System.Application.UI.Views;
using System.IO;
+using System.Windows;
using AvaloniaApplication = Avalonia.Application;
namespace System.Application.UI
@@ -30,6 +31,13 @@ namespace System.Application.UI
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
+ if (!AppHelper.IsOfficialChannelPackage)
+ {
+ MessageBox.Show("The program currently running is not from the official channel.", "Warning",
+ MessageBoxButton.OK,
+ MessageBoxImage.Warning);
+ }
+
desktop.MainWindow = new MainWindow
{
DataContext = DataContext = DI.Get(),
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs
index de1e23903..32eb1c13d 100644
--- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Program.cs
@@ -1,8 +1,7 @@
using Avalonia;
using Avalonia.ReactiveUI;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Logging.Abstractions;
+using NLog;
using System.Application.Models;
using System.Application.Services.Implementation;
using System.Application.UI.ViewModels;
@@ -17,10 +16,26 @@ namespace System.Application.UI
[STAThread]
static void Main(string[] args)
{
- FileSystemDesktop.InitFileSystem();
- ModelValidatorProvider.Init();
- DI.Init(ConfigureServices);
- BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+ var logger = LogManager.GetCurrentClassLogger();
+ try
+ {
+ FileSystemDesktop.InitFileSystem();
+ ModelValidatorProvider.Init();
+ DI.Init(ConfigureServices);
+ BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+ }
+ catch (Exception ex)
+ {
+ AppHelper.EnableLogger = true;
+ // NLog: catch any exception and log it.
+ logger.Error(ex, "Stopped program because of exception");
+ throw;
+ }
+ finally
+ {
+ // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
+ LogManager.Shutdown();
+ }
}
// Avalonia configuration, don't remove; also used by visual designer.
@@ -34,8 +49,8 @@ namespace System.Application.UI
static void ConfigureServices(IServiceCollection services)
{
- // 空日志实现,需要写一个实现替换
- services.AddLogging(l => l.AddProvider(NullLoggerProvider.Instance));
+ // 添加日志实现
+ services.AddDesktopLogging();
// 模型验证框架
services.TryAddModelValidator();
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj b/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj
index 64658bdcf..f44323eda 100644
--- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/System.Application.SteamTools.Client.Desktop.Avalonia.App.csproj
@@ -18,22 +18,22 @@
-
-
-
-
+
+
+
+
-
+
-
+
-
+
@@ -49,7 +49,7 @@
Designer
-
+
diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs
index 6c2119c55..72e68e480 100644
--- a/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs
+++ b/System.Application.SteamTools.Client.Desktop.Avalonia/Windows/MessageBox.cs
@@ -97,6 +97,13 @@ namespace System.Windows
return GetResult(result);
}
+ ///
+ public static async void Show(
+ string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
+ {
+ await ShowAsync(messageBoxText, caption, button, icon);
+ }
+
static Window? GetWindow(IMsBoxWindow window)
{
var _window = window.GetType().GetField("_window", BindingFlags.NonPublic | BindingFlags.Instance);
diff --git a/System.Application.SteamTools.Client.Desktop.Platform.Linux/Implementation/LinuxDesktopPlatformServiceImpl.cs b/System.Application.SteamTools.Client.Desktop.Platform.Linux/Implementation/LinuxDesktopPlatformServiceImpl.cs
index 157df67d0..e49170de0 100644
--- a/System.Application.SteamTools.Client.Desktop.Platform.Linux/Implementation/LinuxDesktopPlatformServiceImpl.cs
+++ b/System.Application.SteamTools.Client.Desktop.Platform.Linux/Implementation/LinuxDesktopPlatformServiceImpl.cs
@@ -1,10 +1,16 @@
-namespace System.Application.Services.Implementation
+using System.Diagnostics;
+
+namespace System.Application.Services.Implementation
{
internal sealed class LinuxDesktopPlatformServiceImpl : IDesktopPlatformService
{
public void SetResizeMode(IntPtr hWnd, int value)
{
+ }
+ public string GetCommandLineArgs(Process process)
+ {
+ return string.Empty;
}
}
}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Platform.Mac/Implementation/MacDesktopPlatformServiceImpl.cs b/System.Application.SteamTools.Client.Desktop.Platform.Mac/Implementation/MacDesktopPlatformServiceImpl.cs
index 3a3fb55f5..b7ebb71bd 100644
--- a/System.Application.SteamTools.Client.Desktop.Platform.Mac/Implementation/MacDesktopPlatformServiceImpl.cs
+++ b/System.Application.SteamTools.Client.Desktop.Platform.Mac/Implementation/MacDesktopPlatformServiceImpl.cs
@@ -1,9 +1,16 @@
-namespace System.Application.Services.Implementation
+using System.Diagnostics;
+
+namespace System.Application.Services.Implementation
{
internal sealed class MacDesktopPlatformServiceImpl : IDesktopPlatformService
{
public void SetResizeMode(IntPtr hWnd, int value)
{
}
+
+ public string GetCommandLineArgs(Process process)
+ {
+ return string.Empty;
+ }
}
}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Platform.Windows/Implementation/WindowsDesktopPlatformServiceImpl.cs b/System.Application.SteamTools.Client.Desktop.Platform.Windows/Implementation/WindowsDesktopPlatformServiceImpl.cs
index 88201cc01..0e33d8fca 100644
--- a/System.Application.SteamTools.Client.Desktop.Platform.Windows/Implementation/WindowsDesktopPlatformServiceImpl.cs
+++ b/System.Application.SteamTools.Client.Desktop.Platform.Windows/Implementation/WindowsDesktopPlatformServiceImpl.cs
@@ -1,4 +1,8 @@
-using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Management;
+using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace System.Application.Services.Implementation
@@ -86,5 +90,22 @@ namespace System.Application.Services.Implementation
}
#endregion
+
+ public string GetCommandLineArgs(Process process)
+ {
+ try
+ {
+ using var searcher = new ManagementObjectSearcher(
+ "SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id);
+ using var objects = searcher.Get();
+ var @object = objects.Cast().SingleOrDefault();
+ return @object?["CommandLine"]?.ToString() ?? "";
+ }
+ catch (Win32Exception ex) when ((uint)ex.ErrorCode == 0x80004005)
+ {
+ // 没有对该进程的安全访问权限。
+ return string.Empty;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop.Platform.Windows/System.Application.SteamTools.Client.Desktop.Platform.Windows.csproj b/System.Application.SteamTools.Client.Desktop.Platform.Windows/System.Application.SteamTools.Client.Desktop.Platform.Windows.csproj
index 941710b14..fedd00562 100644
--- a/System.Application.SteamTools.Client.Desktop.Platform.Windows/System.Application.SteamTools.Client.Desktop.Platform.Windows.csproj
+++ b/System.Application.SteamTools.Client.Desktop.Platform.Windows/System.Application.SteamTools.Client.Desktop.Platform.Windows.csproj
@@ -11,6 +11,10 @@
+
+
+
+
diff --git a/System.Application.SteamTools.Client.Desktop.Platform/IDesktopPlatformService.cs b/System.Application.SteamTools.Client.Desktop.Platform/IDesktopPlatformService.cs
index f8ebaef50..19cf4e631 100644
--- a/System.Application.SteamTools.Client.Desktop.Platform/IDesktopPlatformService.cs
+++ b/System.Application.SteamTools.Client.Desktop.Platform/IDesktopPlatformService.cs
@@ -1,4 +1,5 @@
-using ResizeMode = System.Int32;
+using System.Diagnostics;
+using ResizeMode = System.Int32;
namespace System.Application.Services
{
@@ -6,6 +7,16 @@ namespace System.Application.Services
{
void SetResizeMode(IntPtr hWnd, ResizeMode value);
+ ///
+ /// 获取一个正在运行的进程的命令行参数。
+ /// 与 一样,使用此方法获取的参数是包含应用程序路径的。
+ /// 关于 可参见:
+ /// .NET 命令行参数包含应用程序路径吗?https://blog.walterlv.com/post/when-will-the-command-line-args-contain-the-executable-path.html
+ ///
+ /// 一个正在运行的进程。
+ /// 表示应用程序运行命令行参数的字符串。
+ string GetCommandLineArgs(Process process);
+
public const ResizeMode ResizeMode_NoResize = 0;
public const ResizeMode ResizeMode_CanMinimize = 1;
public const ResizeMode ResizeMode_CanResize = 2;
diff --git a/System.Application.SteamTools.Client.Desktop.Platform/Implementation/DesktopPlatformServiceImpl.cs b/System.Application.SteamTools.Client.Desktop.Platform/Implementation/DesktopPlatformServiceImpl.cs
deleted file mode 100644
index c6512b0ff..000000000
--- a/System.Application.SteamTools.Client.Desktop.Platform/Implementation/DesktopPlatformServiceImpl.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace System.Application.Services.Implementation
-{
- public class DesktopPlatformServiceImpl : IDesktopPlatformService
- {
- public void SetResizeMode(IntPtr hWnd, int value)
- {
- }
- }
-}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop/Extensions/ProcessExtensions.cs b/System.Application.SteamTools.Client.Desktop/Extensions/ProcessExtensions.cs
new file mode 100644
index 000000000..eb8be9339
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/Extensions/ProcessExtensions.cs
@@ -0,0 +1,26 @@
+using System.Application.Services;
+using System.Diagnostics;
+
+namespace System.Application.Extensions
+{
+ ///
+ /// 为 类型提供扩展方法
+ ///
+ public static class ProcessExtensions
+ {
+ ///
+ public static string GetCommandLineArgs(this Process process)
+ {
+ try
+ {
+ var p = DI.Get();
+ return p.GetCommandLineArgs(process);
+ }
+ catch (InvalidOperationException)
+ {
+ // 进程已退出。
+ return string.Empty;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop/Extensions/StartupArgsExtensions.cs b/System.Application.SteamTools.Client.Desktop/Extensions/StartupArgsExtensions.cs
new file mode 100644
index 000000000..5a8c3d288
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/Extensions/StartupArgsExtensions.cs
@@ -0,0 +1,52 @@
+// ReSharper disable once CheckNamespace
+namespace System.Application
+{
+ public static class StartupArgsExtensions
+ {
+ public static bool ContainsArg(this string[] args, string arg)
+ {
+ for (var i = 0; i < args.Length; i++)
+ {
+ if (string.Equals(args[i], arg, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static bool ContainsArg(this string[] args, string arg, out string value)
+ {
+ value = "";
+ for (var i = 0; i < args.Length; i++)
+ {
+ if (string.Equals(args[i], arg, StringComparison.OrdinalIgnoreCase))
+ {
+ if (args.Length > i + 1)
+ {
+ value = args[i + 1];
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static bool ContainsArg(this string[] args, string arg, out int value)
+ {
+ value = 0;
+ for (var i = 0; i < args.Length; i++)
+ {
+ if (string.Equals(args[i], arg, StringComparison.OrdinalIgnoreCase))
+ {
+ if (args.Length > i + 1 && int.TryParse(args[i + 1], out int val))
+ {
+ value = val;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop/ServiceCollectionExtensions.cs b/System.Application.SteamTools.Client.Desktop/ServiceCollectionExtensions.cs
index f4f1126fc..eef5e5a2f 100644
--- a/System.Application.SteamTools.Client.Desktop/ServiceCollectionExtensions.cs
+++ b/System.Application.SteamTools.Client.Desktop/ServiceCollectionExtensions.cs
@@ -1,8 +1,7 @@
-using Microsoft.Extensions.DependencyInjection.Extensions;
-using System.Application.Services;
+using System.Application.Services;
using System.Application.Services.Implementation;
+using System.Application.UI;
using System.Application.UI.ViewModels;
-using System.Security;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
@@ -43,5 +42,16 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddSingleton();
return services;
}
+
+ ///
+ /// 添加桌面端日志实现
+ ///
+ ///
+ ///
+ public static IServiceCollection AddDesktopLogging(this IServiceCollection services)
+ {
+ services.AddLogging(AppHelper.Configure);
+ return services;
+ }
}
}
\ No newline at end of file
diff --git a/System.Application.SteamTools.Client.Desktop/Services/OperationResult.cs b/System.Application.SteamTools.Client.Desktop/Services/OperationResult.cs
new file mode 100644
index 000000000..ab02126e8
--- /dev/null
+++ b/System.Application.SteamTools.Client.Desktop/Services/OperationResult.cs
@@ -0,0 +1,102 @@
+namespace System.Application.Services
+{
+ ///
+ /// 操作结果信息类,对操作结果进行封装
+ ///
+ ///
+ public class OperationResult
+ {
+ #region 构造函数
+
+ public OperationResult()
+ {
+ ResultType = OperationResultType.Error;
+ }
+
+ ///
+ /// 初始化一个 操作结果信息类 的新实例
+ ///
+ /// 操作结果类型
+ public OperationResult(OperationResultType resultType)
+ {
+ ResultType = resultType;
+ }
+
+ ///
+ /// 初始化一个 定义返回消息的操作结果信息类 的新实例
+ ///
+ /// 操作结果类型
+ /// 返回消息
+ public OperationResult(OperationResultType resultType, string message)
+ : this(resultType)
+ {
+ Message = message;
+ }
+
+ ///
+ /// 初始化一个 定义返回消息与附加数据的操作结果信息类 的新实例
+ ///
+ /// 操作结果类型
+ /// 返回消息
+ /// 返回数据
+ public OperationResult(OperationResultType resultType, string message, T appendData)
+ : this(resultType, message)
+ {
+ AppendData = appendData;
+ }
+
+ ///
+ /// 初始化一个 定义返回消息与日志消息的操作结果信息类 的新实例
+ ///
+ /// 操作结果类型
+ /// 返回消息
+ /// 日志记录消息
+ public OperationResult(OperationResultType resultType, string message, string logMessage)
+ : this(resultType, message)
+ {
+ LogMessage = logMessage;
+ }
+
+ ///
+ /// 初始化一个 定义返回消息、日志消息与附加数据的操作结果信息类 的新实例
+ ///
+ /// 操作结果类型
+ /// 返回消息
+ /// 日志记录消息
+ /// 返回数据
+ public OperationResult(OperationResultType resultType, string message, string logMessage, T appendData)
+ : this(resultType, message, logMessage)
+ {
+ AppendData = appendData;
+ }
+
+ #endregion
+
+ #region 属性
+
+ ///
+ /// 获取或设置 操作结果类型
+ ///
+ public OperationResultType ResultType { get; set; }
+
+ ///
+ /// 获取或设置 操作返回信息
+ ///
+ public string? Message { get; set; }
+
+ ///
+ /// 获取或设置 操作返回的日志消息,用于记录日志
+ ///
+ public string? LogMessage { get; set; }
+
+ ///
+ /// 获取或设置 操作结果附加信息
+ ///
+ public T? AppendData { get; set; }
+
+ #endregion
+ }
+
+ ///
+ public class OperationResult : OperationResult