From f823e0f372d3eac2632bdf6d2a1cd9585e5b0ae6 Mon Sep 17 00:00:00 2001 From: lichx Date: Tue, 12 Mar 2024 16:15:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CSS_Solution.sln | 25 ++ CSS_Solution/AppSettings.json | 69 ++++ CSS_Solution/CSS_Solution.csproj | 60 +++ CSS_Solution/ExceptionHandler.cs | 54 +++ .../Forms/Change_Task_Form.Designer.cs | 59 +++ CSS_Solution/Forms/Change_Task_Form.cs | 20 + CSS_Solution/Forms/Change_Task_Form.resx | 120 ++++++ CSS_Solution/Forms/Countdown.Designer.cs | 136 +++++++ CSS_Solution/Forms/Countdown.cs | 39 ++ CSS_Solution/Forms/Countdown.resx | 123 +++++++ CSS_Solution/Forms/Form_Adjustment.cs | 199 ++++++++++ CSS_Solution/Forms/MainForm.Designer.cs | 268 ++++++++++++++ CSS_Solution/Forms/MainForm.cs | 61 ++++ CSS_Solution/Forms/MainForm.resx | 126 +++++++ CSS_Solution/Forms/Settings_Form.Designer.cs | 60 +++ CSS_Solution/Forms/Settings_Form.cs | 20 + CSS_Solution/Forms/Settings_Form.resx | 120 ++++++ CSS_Solution/Forms/Task_Run_Form.Designer.cs | 59 +++ CSS_Solution/Forms/Task_Run_Form.cs | 20 + CSS_Solution/Forms/Task_Run_Form.resx | 120 ++++++ CSS_Solution/Forms/Welcome_Form.Designer.cs | 166 +++++++++ CSS_Solution/Forms/Welcome_Form.cs | 78 ++++ CSS_Solution/Forms/Welcome_Form.resx | 120 ++++++ CSS_Solution/Program.cs | 111 ++++++ CSS_Solution/Properties/Resources.Designer.cs | 103 ++++++ CSS_Solution/Properties/Resources.resx | 133 +++++++ CSS_Solution/Request/Course_Request.cs | 12 + CSS_Solution/Request/Get_Index.cs | 80 ++++ CSS_Solution/Request/HttpClientPool.cs | 25 ++ CSS_Solution/Request/IRequest.cs | 15 + CSS_Solution/Request/Login.cs | 103 ++++++ CSS_Solution/Request/RequestResults.cs | 138 +++++++ CSS_Solution/Request/Task_handler.cs | 181 +++++++++ CSS_Solution/Request/To_Course.cs | 121 ++++++ CSS_Solution/Resources/Run.png | Bin 0 -> 4827 bytes CSS_Solution/Resources/home.png | Bin 0 -> 7345 bytes CSS_Solution/Resources/input.png | Bin 0 -> 5110 bytes CSS_Solution/Resources/settings.png | Bin 0 -> 6698 bytes CSS_Solution/Settings.cs | 345 ++++++++++++++++++ 39 files changed, 3489 insertions(+) create mode 100644 CSS_Solution.sln create mode 100644 CSS_Solution/AppSettings.json create mode 100644 CSS_Solution/CSS_Solution.csproj create mode 100644 CSS_Solution/ExceptionHandler.cs create mode 100644 CSS_Solution/Forms/Change_Task_Form.Designer.cs create mode 100644 CSS_Solution/Forms/Change_Task_Form.cs create mode 100644 CSS_Solution/Forms/Change_Task_Form.resx create mode 100644 CSS_Solution/Forms/Countdown.Designer.cs create mode 100644 CSS_Solution/Forms/Countdown.cs create mode 100644 CSS_Solution/Forms/Countdown.resx create mode 100644 CSS_Solution/Forms/Form_Adjustment.cs create mode 100644 CSS_Solution/Forms/MainForm.Designer.cs create mode 100644 CSS_Solution/Forms/MainForm.cs create mode 100644 CSS_Solution/Forms/MainForm.resx create mode 100644 CSS_Solution/Forms/Settings_Form.Designer.cs create mode 100644 CSS_Solution/Forms/Settings_Form.cs create mode 100644 CSS_Solution/Forms/Settings_Form.resx create mode 100644 CSS_Solution/Forms/Task_Run_Form.Designer.cs create mode 100644 CSS_Solution/Forms/Task_Run_Form.cs create mode 100644 CSS_Solution/Forms/Task_Run_Form.resx create mode 100644 CSS_Solution/Forms/Welcome_Form.Designer.cs create mode 100644 CSS_Solution/Forms/Welcome_Form.cs create mode 100644 CSS_Solution/Forms/Welcome_Form.resx create mode 100644 CSS_Solution/Program.cs create mode 100644 CSS_Solution/Properties/Resources.Designer.cs create mode 100644 CSS_Solution/Properties/Resources.resx create mode 100644 CSS_Solution/Request/Course_Request.cs create mode 100644 CSS_Solution/Request/Get_Index.cs create mode 100644 CSS_Solution/Request/HttpClientPool.cs create mode 100644 CSS_Solution/Request/IRequest.cs create mode 100644 CSS_Solution/Request/Login.cs create mode 100644 CSS_Solution/Request/RequestResults.cs create mode 100644 CSS_Solution/Request/Task_handler.cs create mode 100644 CSS_Solution/Request/To_Course.cs create mode 100644 CSS_Solution/Resources/Run.png create mode 100644 CSS_Solution/Resources/home.png create mode 100644 CSS_Solution/Resources/input.png create mode 100644 CSS_Solution/Resources/settings.png create mode 100644 CSS_Solution/Settings.cs diff --git a/CSS_Solution.sln b/CSS_Solution.sln new file mode 100644 index 0000000..be3c81d --- /dev/null +++ b/CSS_Solution.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34607.119 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSS_Solution", "CSS_Solution\CSS_Solution.csproj", "{F33E856E-A528-459E-8B18-5661ED2CFE1B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F33E856E-A528-459E-8B18-5661ED2CFE1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F33E856E-A528-459E-8B18-5661ED2CFE1B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F33E856E-A528-459E-8B18-5661ED2CFE1B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F33E856E-A528-459E-8B18-5661ED2CFE1B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8B6677EC-62A4-4038-8AD6-C1EEA25762C7} + EndGlobalSection +EndGlobal diff --git a/CSS_Solution/AppSettings.json b/CSS_Solution/AppSettings.json new file mode 100644 index 0000000..f6f59cf --- /dev/null +++ b/CSS_Solution/AppSettings.json @@ -0,0 +1,69 @@ +{ + "login_index": "http://sso.jwc.whut.edu.cn/Certification/login.do", + "getcode": "http://sso.jwc.whut.edu.cn/Certification/getCode.do", + "getIndex_headers": { + "User_Agent": "Apifox/1.0.0 (https://apifox.com)", + "Accept": "*/*", + "Host": "sso.jwc.whut.edu.cn", + "Accept_Encoding": "gzip, deflate, br", + "Connection": "keep-alive" + }, + "getCode_headers": { + "User_Agent": "Apifox/1.0.0 (https://apifox.com)", + "Accept": "*/*", + "Host": "sso.jwc.whut.edu.cn", + "Accept_Encoding": "gzip, deflate, br", + "Connection": "keep-alive", + "Content_Type": "application/x-www-form-urlencoded", + "Content_Length": "42" + }, + "getcode_body": { + "webfinger": "b9a7a7901c83c4c0dad90bd2bbf19498" + }, + "login": "http://sso.jwc.whut.edu.cn/Certification/login.do", + "login_header": { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept_Encoding": "gzip, deflate", + "Accept_Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + "Cache_Control": "max-age=0", + "Content_Length": "246", + "Content_Type": "application/x-www-form-urlencoded", + "Host": "sso.jwc.whut.edu.cn", + "Origin": "http://sso.jwc.whut.edu.cn", + "Referer": "http://sso.jwc.whut.edu.cn/Certification/login.do", + "Upgrade_Insecure_Requests": "1", + "Keep_Alive": "timeout=4", + "User_Agent": "Apifox/1.0.0 (https://apifox.com)", + "Connection": "keep-alive" + }, + "login_body": { + "MsgID": "", + "KeyID": "", + "UserName": "", + "Password": "", + "rnd": "FromIndex", + "return_EncData": "", + "code": "FromGetCode", + "userName1": "", + "password1": "", + "webfinger": "b9a7a7901c83c4c0dad90bd2bbf19498", + "falg": "", + "type": "xs", + "userName_": "", + "password_": "" + }, + "to_course_header": { + "User_Agent": "Apifox/1.0.0 (https://apifox.com)", + "Accept": "*/*", + "Accept_Encoding": "gzip, deflate", + "Accept_Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + "Referer": "http://sso.jwc.whut.edu.cn/", + "Upgrade_Insecure_Requests": "1", + "Connection": "keep-alive" + }, + "to_course": "http://218.197.102.183/Course", + "Suggest_Client_count": "4", + "Etc": { + "StartTime_Str": "2004-1-1-1-1-1" + } +} diff --git a/CSS_Solution/CSS_Solution.csproj b/CSS_Solution/CSS_Solution.csproj new file mode 100644 index 0000000..da91d00 --- /dev/null +++ b/CSS_Solution/CSS_Solution.csproj @@ -0,0 +1,60 @@ + + + + Exe + net8.0-windows8.0 + enable + True + enable + False + False + + + + False + True + + + + False + True + + + + + + + + + + + + + + + + + + + + + Always + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/CSS_Solution/ExceptionHandler.cs b/CSS_Solution/ExceptionHandler.cs new file mode 100644 index 0000000..786133c --- /dev/null +++ b/CSS_Solution/ExceptionHandler.cs @@ -0,0 +1,54 @@ +using Microsoft.Extensions.Logging; +using System.Configuration; + +namespace CSS_Solution +{ + internal class ExceptionHandler + { + ILogger? exception_logger; + public ExceptionHandler() + { + exception_logger = Initialize.loggerFactory?.CreateLogger("Global exception"); + if(exception_logger == null) + throw new Exception("logger create failed"); + } + public void ApplicationThreadExceptionHandler(object sender, System.Threading.ThreadExceptionEventArgs e) + { + Exception exception = e.Exception; + if (exception_logger == null) + { + exception_logger = Initialize.default_logger != null ? Initialize.default_logger : LoggerFactory.Create(builder => + { + Console.WriteLine(builder); + builder.AddConsole(); + }).CreateLogger("Global exception"); + if (exception_logger == null) + { + Console.WriteLine($"[{DateTime.Now}] Weird!! Logger can't be initialized!"); + Console.WriteLine($"[{DateTime.Now}] However, an exception has been caught"); + Console.WriteLine($"[{DateTime.Now}] Message:\n{exception.Message}\nStackTrace:\n{exception.StackTrace}\n"); + Program.mainForm?.Close(); + return; + } + else + exception_logger.LogWarning($"[{DateTime.Now}] Something wrong with the exception logger, you should check it out."); + } + if (exception == null) + { + exception_logger.LogWarning($"[{DateTime.Now}] Weird!! Null exception catched"); + return; + } + string info = $"[{DateTime.Now}] Message:\n{exception.Message}\nStackTrace:\n{exception.StackTrace}\n"; + switch (exception) + { + case ConfigurationErrorsException: + exception_logger.LogError(info); + break; + default: + exception_logger.LogWarning(info); + break; + } + } + } + +} diff --git a/CSS_Solution/Forms/Change_Task_Form.Designer.cs b/CSS_Solution/Forms/Change_Task_Form.Designer.cs new file mode 100644 index 0000000..17062e5 --- /dev/null +++ b/CSS_Solution/Forms/Change_Task_Form.Designer.cs @@ -0,0 +1,59 @@ +namespace CSS_Solution.Forms +{ + partial class Change_Task_Form + { + /// + /// 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() + { + label1 = new Label(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(12, 9); + label1.Name = "label1"; + label1.Size = new Size(22, 24); + label1.TabIndex = 1; + label1.Text = "b"; + // + // Change_Task_Form + // + AutoScaleDimensions = new SizeF(11F, 24F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(label1); + Name = "Change_Task_Form"; + Text = "Change_Task_Form"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label label1; + } +} \ No newline at end of file diff --git a/CSS_Solution/Forms/Change_Task_Form.cs b/CSS_Solution/Forms/Change_Task_Form.cs new file mode 100644 index 0000000..2fa46bc --- /dev/null +++ b/CSS_Solution/Forms/Change_Task_Form.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CSS_Solution.Forms +{ + public partial class Change_Task_Form : Form + { + public Change_Task_Form() + { + InitializeComponent(); + } + } +} diff --git a/CSS_Solution/Forms/Change_Task_Form.resx b/CSS_Solution/Forms/Change_Task_Form.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/CSS_Solution/Forms/Change_Task_Form.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/CSS_Solution/Forms/Countdown.Designer.cs b/CSS_Solution/Forms/Countdown.Designer.cs new file mode 100644 index 0000000..d5f57b9 --- /dev/null +++ b/CSS_Solution/Forms/Countdown.Designer.cs @@ -0,0 +1,136 @@ +namespace CSS_Solution.Forms +{ + partial class Countdown + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region 组件设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + Title = new Label(); + Delta_Time = new Label(); + millisecond = new Label(); + inaccuracies = new Label(); + info2 = new Label(); + info1 = new Label(); + refresh = new System.Windows.Forms.Timer(components); + SuspendLayout(); + // + // Title + // + Title.AutoSize = true; + Title.Font = new Font("Microsoft YaHei UI", 28F, FontStyle.Regular, GraphicsUnit.Point, 134); + Title.ForeColor = Color.White; + Title.Location = new Point(0, 0); + Title.Name = "Title"; + Title.Size = new Size(163, 75); + Title.TabIndex = 12; + Title.Text = "Time"; + // + // Delta_Time + // + Delta_Time.Font = new Font("Microsoft YaHei UI", 42F, FontStyle.Regular, GraphicsUnit.Point, 134); + Delta_Time.ForeColor = Color.White; + Delta_Time.Location = new Point(-8, 54); + Delta_Time.Name = "Delta_Time"; + Delta_Time.Size = new Size(430, 110); + Delta_Time.TabIndex = 13; + Delta_Time.Text = "00:00:00"; + // + // millisecond + // + millisecond.AutoSize = true; + millisecond.ForeColor = Color.White; + millisecond.Location = new Point(348, 122); + millisecond.Name = "millisecond"; + millisecond.Size = new Size(32, 24); + millisecond.TabIndex = 14; + millisecond.Text = "00"; + // + // inaccuracies + // + inaccuracies.AutoSize = true; + inaccuracies.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); + inaccuracies.ForeColor = Color.White; + inaccuracies.Location = new Point(343, 67); + inaccuracies.Name = "inaccuracies"; + inaccuracies.Size = new Size(42, 31); + inaccuracies.TabIndex = 15; + inaccuracies.Text = "+-"; + // + // info2 + // + info2.AutoSize = true; + info2.ForeColor = Color.White; + info2.Location = new Point(11, 191); + info2.Name = "info2"; + info2.Size = new Size(273, 24); + info2.TabIndex = 16; + info2.Text = "START OF COURSE SELECTION"; + // + // info1 + // + info1.AutoSize = true; + info1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); + info1.ForeColor = Color.White; + info1.Location = new Point(8, 155); + info1.Name = "info1"; + info1.Size = new Size(131, 31); + info1.TabIndex = 17; + info1.Text = "EXPECTED"; + // + // refresh + // + refresh.Interval = 10; + refresh.Tick += refresh_Tick; + // + // Countdown + // + AutoScaleDimensions = new SizeF(11F, 24F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = Color.FromArgb(25, 25, 25); + Controls.Add(Title); + Controls.Add(info1); + Controls.Add(info2); + Controls.Add(millisecond); + Controls.Add(inaccuracies); + Controls.Add(Delta_Time); + Name = "Countdown"; + Size = new Size(390, 226); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label Title; + private Label Delta_Time; + private Label millisecond; + private Label inaccuracies; + private Label info2; + private Label info1; + private System.Windows.Forms.Timer refresh; + } +} diff --git a/CSS_Solution/Forms/Countdown.cs b/CSS_Solution/Forms/Countdown.cs new file mode 100644 index 0000000..2539a3a --- /dev/null +++ b/CSS_Solution/Forms/Countdown.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using CSS_Solution; +namespace CSS_Solution.Forms +{ + public partial class Countdown : UserControl + { + public Countdown() + { + InitializeComponent(); + refresh.Enabled = true; + } + public void Start_Timer() => millisecond.Enabled = true; + + private void refresh_Tick(object sender, EventArgs e) + { + if(DesignMode) return; + DateTime start = DateTime.Now; + DateTime end = Settings.etc.StartTime; + //DateTime end = DateTime.Now; + TimeSpan duration = end - start; + if (duration < TimeSpan.Zero) + { + refresh.Enabled = false; + Delta_Time.Text = "00:00:00"; + millisecond.Text = "00"; + } + Delta_Time.Text = duration.ToString(@"hh\:mm\:ss"); + millisecond.Text = duration.ToString(@"fff").Remove(2); + } + } +} diff --git a/CSS_Solution/Forms/Countdown.resx b/CSS_Solution/Forms/Countdown.resx new file mode 100644 index 0000000..fcecb8f --- /dev/null +++ b/CSS_Solution/Forms/Countdown.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + \ No newline at end of file diff --git a/CSS_Solution/Forms/Form_Adjustment.cs b/CSS_Solution/Forms/Form_Adjustment.cs new file mode 100644 index 0000000..9760cbe --- /dev/null +++ b/CSS_Solution/Forms/Form_Adjustment.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSS_Solution.Forms +{ + partial class MainForm + { + private Point mPoint; + private void Title_MouseMove(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + Location = new Point(Location.X + e.X - mPoint.X, Location.Y + e.Y - mPoint.Y); + } + private void Title_MouseDown(object sender, MouseEventArgs e) + { + mPoint = new Point(e.X, e.Y); + } + //enum Adjustment_position + //{ + // LeftTop = 0, + // Top = 1, + // RightTop = 2, + // Right = 3, + // RightBottom = 4, + // Bottom = 5, + // LeftBottom = 6, + // Left = 7, + // Middle = 8 + //} + //Adjustment_position adjustment_Position = Adjustment_position.Middle; + //private void Main_MouseMove(object sender, MouseEventArgs e) + //{ + + // if (e.Button == MouseButtons.Left) + // { + // switch (adjustment_Position) + // { + // case Adjustment_position.LeftTop: + // { + // int endx = Left + Width; + // Left = MousePosition.X; + // Width = endx - Left; + // int endy = Top + Height; + // Top = MousePosition.Y; + // Height = endy - Top; + // break; + // } + // case Adjustment_position.Top: + // { + // int endy = Top + Height; + // Top = MousePosition.Y; + // Height = endy - Top; + // break; + // } + // case Adjustment_position.RightTop: + // { + // int endy = Top + Height; + // Top = MousePosition.Y; + // Width = MousePosition.X - Left; + // Height = endy - Top; + // break; + // } + // case Adjustment_position.Right: + // { + // Width = MousePosition.X - Left; + // break; + // } + // case Adjustment_position.RightBottom: + // { + // Width = MousePosition.X - Left; + // Height = MousePosition.Y - Top; + // break; + // } + // case Adjustment_position.Bottom: + // { + // Height = MousePosition.Y - Top; + // break; + // } + // case Adjustment_position.LeftBottom: + // { + // int endx = Left + Width; + // Left = MousePosition.X; + // Width = endx - Left; + // Height = MousePosition.Y - Top; + // break; + // } + // case Adjustment_position.Left: + // { + // int endx = Left + Width; + // Left = MousePosition.X; + // Width = endx - Left; + // break; + // } + // } + // } + // if (e.Location.X >= Width - 4 && e.Location.Y >= Height - 4) + // { + // Cursor = Cursors.SizeNWSE; //RightBottom + // adjustment_Position = Adjustment_position.RightBottom; + // } + // else if (e.Location.X >= Width - 4 && e.Location.Y <= 4) + // { + // Cursor = Cursors.SizeNESW; //RightTop + // adjustment_Position = Adjustment_position.RightTop; + // } + // else if (e.Location.X <= 4 && e.Location.Y >= Height - 4) + // { + // Cursor = Cursors.SizeNESW; //LeftBottom + // adjustment_Position = Adjustment_position.LeftBottom; + // } + // else if (e.Location.X <= 4 && e.Location.Y <= 4) + // { + // Cursor = Cursors.SizeNWSE; //LeftTop + // adjustment_Position = Adjustment_position.LeftTop; + // } + // else if (e.Location.X >= Width - 4) + // { + // Cursor = Cursors.SizeWE; //Right + // adjustment_Position = Adjustment_position.Right; + // } + // else if (e.Location.X <= 4) + // { + // Cursor = Cursors.SizeWE; //Left + // adjustment_Position = Adjustment_position.Left; + // } + // else if (e.Location.Y >= Height - 4) + // { + // Cursor = Cursors.SizeNS; //Bottom + // adjustment_Position = Adjustment_position.Bottom; + // } + // else if (e.Location.Y <= 4) + // { + // Cursor = Cursors.SizeNS; //Top + // adjustment_Position = Adjustment_position.Top; + // } + // else + // { + // Cursor = Cursors.Arrow; //Middle + // adjustment_Position = Adjustment_position.Middle; + // } + //} + + //private void Main_Leave(object sender, EventArgs e) + //{ + // Cursor = Cursors.Arrow;// 移出窗体变为正常 + //} + #region 支持改变窗体大小 + private const int Guying_HTLEFT = 10; + private const int Guying_HTRIGHT = 11; + private const int Guying_HTTOP = 12; + private const int Guying_HTTOPLEFT = 13; + private const int Guying_HTTOPRIGHT = 14; + private const int Guying_HTBOTTOM = 15; + private const int Guying_HTBOTTOMLEFT = 0x10; + private const int Guying_HTBOTTOMRIGHT = 17; + protected override void WndProc(ref Message m) + { + switch (m.Msg) + { + case 0x0084: + base.WndProc(ref m); + Point vPoint = new Point((int)m.LParam & 0xFFFF, (int)m.LParam >> 16 & 0xFFFF); + vPoint = PointToClient(vPoint); + if (vPoint.X <= 5) + if (vPoint.Y <= 5) + m.Result = (IntPtr)Guying_HTTOPLEFT; + else if (vPoint.Y >= ClientSize.Height - 5) + m.Result = (IntPtr)Guying_HTBOTTOMLEFT; + else + m.Result = (IntPtr)Guying_HTLEFT; + else if (vPoint.X >= ClientSize.Width - 5) + if (vPoint.Y <= 5) + m.Result = (IntPtr)Guying_HTTOPRIGHT; + else if (vPoint.Y >= ClientSize.Height - 5) + m.Result = (IntPtr)Guying_HTBOTTOMRIGHT; + else + m.Result = (IntPtr)Guying_HTRIGHT; + else if (vPoint.Y <= 5) + m.Result = (IntPtr)Guying_HTTOP; + else if (vPoint.Y >= ClientSize.Height - 5) + m.Result = (IntPtr)Guying_HTBOTTOM; + break; + case 0x0201://鼠标左键按下的消息 + m.Msg = 0x00A1;//更改消息为非客户区按下鼠标 + m.LParam = IntPtr.Zero; //默认值 + m.WParam = new IntPtr(2);//鼠标放在标题栏内 + base.WndProc(ref m); + break; + default: + base.WndProc(ref m); + break; + } + } + #endregion + } +} diff --git a/CSS_Solution/Forms/MainForm.Designer.cs b/CSS_Solution/Forms/MainForm.Designer.cs new file mode 100644 index 0000000..840ce84 --- /dev/null +++ b/CSS_Solution/Forms/MainForm.Designer.cs @@ -0,0 +1,268 @@ +namespace CSS_Solution.Forms +{ + partial class MainForm + { + /// + /// 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() + { + components = new System.ComponentModel.Container(); + MainPanel = new Panel(); + FunctionPanel = new Panel(); + SideBar = new Panel(); + SettingsPanel = new Panel(); + SettingsPicture = new PictureBox(); + HomePanel = new Panel(); + HomePicture = new PictureBox(); + RunTaskPanel = new Panel(); + RunTaskPicture = new PictureBox(); + SetTaskPanel = new Panel(); + SetTaskPicture = new PictureBox(); + Title = new Panel(); + Title_name = new Label(); + statusStrip = new StatusStrip(); + timer1 = new System.Windows.Forms.Timer(components); + MainPanel.SuspendLayout(); + SideBar.SuspendLayout(); + SettingsPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)SettingsPicture).BeginInit(); + HomePanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)HomePicture).BeginInit(); + RunTaskPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)RunTaskPicture).BeginInit(); + SetTaskPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)SetTaskPicture).BeginInit(); + Title.SuspendLayout(); + SuspendLayout(); + // + // MainPanel + // + MainPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + MainPanel.BackColor = Color.FromArgb(25, 25, 25); + MainPanel.Controls.Add(FunctionPanel); + MainPanel.Controls.Add(SideBar); + MainPanel.Controls.Add(Title); + MainPanel.Controls.Add(statusStrip); + MainPanel.ForeColor = Color.White; + MainPanel.Location = new Point(3, 3); + MainPanel.Margin = new Padding(0); + MainPanel.Name = "MainPanel"; + MainPanel.Size = new Size(1484, 814); + MainPanel.TabIndex = 5; + // + // FunctionPanel + // + FunctionPanel.Dock = DockStyle.Fill; + FunctionPanel.Location = new Point(81, 56); + FunctionPanel.Name = "FunctionPanel"; + FunctionPanel.Size = new Size(1403, 736); + FunctionPanel.TabIndex = 2; + // + // SideBar + // + SideBar.BackColor = Color.FromArgb(26, 32, 45); + SideBar.Controls.Add(SettingsPanel); + SideBar.Controls.Add(HomePanel); + SideBar.Controls.Add(RunTaskPanel); + SideBar.Controls.Add(SetTaskPanel); + SideBar.Dock = DockStyle.Left; + SideBar.Location = new Point(0, 56); + SideBar.Name = "SideBar"; + SideBar.Size = new Size(81, 736); + SideBar.TabIndex = 1; + // + // SettingsPanel + // + SettingsPanel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + SettingsPanel.Controls.Add(SettingsPicture); + SettingsPanel.Location = new Point(10, 637); + SettingsPanel.Name = "SettingsPanel"; + SettingsPanel.Size = new Size(61, 61); + SettingsPanel.TabIndex = 4; + SettingsPanel.Click += SwitchPanels_Click; + SettingsPanel.MouseEnter += SwitchPanels_MouseEnter; + // + // SettingsPicture + // + SettingsPicture.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + SettingsPicture.Image = Properties.Resources.settings; + SettingsPicture.Location = new Point(15, 15); + SettingsPicture.Name = "SettingsPicture"; + SettingsPicture.Size = new Size(31, 31); + SettingsPicture.SizeMode = PictureBoxSizeMode.Zoom; + SettingsPicture.TabIndex = 1; + SettingsPicture.TabStop = false; + SettingsPicture.Click += SwitchPanels_Click; + SettingsPicture.MouseEnter += SwitchPanels_MouseEnter; + // + // HomePanel + // + HomePanel.Controls.Add(HomePicture); + HomePanel.Location = new Point(10, 10); + HomePanel.Name = "HomePanel"; + HomePanel.Size = new Size(61, 61); + HomePanel.TabIndex = 3; + HomePanel.Click += SwitchPanels_Click; + HomePanel.MouseEnter += SwitchPanels_MouseEnter; + // + // HomePicture + // + HomePicture.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + HomePicture.Image = Properties.Resources.home; + HomePicture.Location = new Point(15, 15); + HomePicture.Name = "HomePicture"; + HomePicture.Size = new Size(31, 31); + HomePicture.SizeMode = PictureBoxSizeMode.Zoom; + HomePicture.TabIndex = 2; + HomePicture.TabStop = false; + HomePicture.Click += SwitchPanels_Click; + HomePicture.MouseEnter += SwitchPanels_MouseEnter; + // + // RunTaskPanel + // + RunTaskPanel.Controls.Add(RunTaskPicture); + RunTaskPanel.Location = new Point(10, 152); + RunTaskPanel.Name = "RunTaskPanel"; + RunTaskPanel.Size = new Size(61, 61); + RunTaskPanel.TabIndex = 2; + RunTaskPanel.Click += SwitchPanels_Click; + RunTaskPanel.MouseEnter += SwitchPanels_MouseEnter; + // + // RunTaskPicture + // + RunTaskPicture.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + RunTaskPicture.Image = Properties.Resources.Run; + RunTaskPicture.Location = new Point(15, 15); + RunTaskPicture.Name = "RunTaskPicture"; + RunTaskPicture.Size = new Size(31, 31); + RunTaskPicture.SizeMode = PictureBoxSizeMode.Zoom; + RunTaskPicture.TabIndex = 1; + RunTaskPicture.TabStop = false; + RunTaskPicture.Click += SwitchPanels_Click; + RunTaskPicture.MouseEnter += SwitchPanels_MouseEnter; + // + // SetTaskPanel + // + SetTaskPanel.Controls.Add(SetTaskPicture); + SetTaskPanel.Location = new Point(10, 81); + SetTaskPanel.Name = "SetTaskPanel"; + SetTaskPanel.Size = new Size(61, 61); + SetTaskPanel.TabIndex = 1; + SetTaskPanel.Click += SwitchPanels_Click; + SetTaskPanel.MouseEnter += SwitchPanels_MouseEnter; + // + // SetTaskPicture + // + SetTaskPicture.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + SetTaskPicture.Image = Properties.Resources.input; + SetTaskPicture.Location = new Point(15, 15); + SetTaskPicture.Name = "SetTaskPicture"; + SetTaskPicture.Size = new Size(31, 31); + SetTaskPicture.SizeMode = PictureBoxSizeMode.Zoom; + SetTaskPicture.TabIndex = 0; + SetTaskPicture.TabStop = false; + SetTaskPicture.Click += SwitchPanels_Click; + SetTaskPicture.MouseEnter += SwitchPanels_MouseEnter; + // + // Title + // + Title.BackColor = Color.FromArgb(26, 32, 45); + Title.Controls.Add(Title_name); + Title.Dock = DockStyle.Top; + Title.Location = new Point(0, 0); + Title.Name = "Title"; + Title.Size = new Size(1484, 56); + Title.TabIndex = 0; + Title.MouseDown += Title_MouseDown; + Title.MouseMove += Title_MouseMove; + // + // Title_name + // + Title_name.AutoSize = true; + Title_name.Font = new Font("Microsoft YaHei UI", 16F, FontStyle.Bold, GraphicsUnit.Point, 134); + Title_name.Location = new Point(5, 5); + Title_name.Name = "Title_name"; + Title_name.Size = new Size(686, 42); + Title_name.TabIndex = 2; + Title_name.Text = "Course selection system Solution (C.s.s.S)"; + // + // statusStrip + // + statusStrip.BackColor = Color.FromArgb(0, 122, 204); + statusStrip.ImageScalingSize = new Size(24, 24); + statusStrip.Location = new Point(0, 792); + statusStrip.Name = "statusStrip"; + statusStrip.Size = new Size(1484, 22); + statusStrip.TabIndex = 3; + statusStrip.Text = "statusStrip1"; + // + // MainForm + // + AutoScaleDimensions = new SizeF(11F, 24F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = Color.FromArgb(0, 122, 204); + ClientSize = new Size(1490, 820); + Controls.Add(MainPanel); + DoubleBuffered = true; + FormBorderStyle = FormBorderStyle.None; + MinimumSize = new Size(775, 378); + Name = "MainForm"; + Text = "MainForm"; + MainPanel.ResumeLayout(false); + MainPanel.PerformLayout(); + SideBar.ResumeLayout(false); + SettingsPanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)SettingsPicture).EndInit(); + HomePanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)HomePicture).EndInit(); + RunTaskPanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)RunTaskPicture).EndInit(); + SetTaskPanel.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)SetTaskPicture).EndInit(); + Title.ResumeLayout(false); + Title.PerformLayout(); + ResumeLayout(false); + } + + #endregion + private Panel Title; + private FlowLayoutPanel flowLayoutPanel1; + private Panel top; + private Panel MainPanel; + private Panel SideBar; + private Label Title_name; + private PictureBox SetTaskPicture; + private Panel SetTaskPanel; + private Panel FunctionPanel; + private PictureBox RunTaskPicture; + private Panel RunTaskPanel; + private Panel HomePanel; + private PictureBox HomePicture; + private Panel SettingsPanel; + private PictureBox SettingsPicture; + private StatusStrip statusStrip; + private System.Windows.Forms.Timer timer1; + } +} \ No newline at end of file diff --git a/CSS_Solution/Forms/MainForm.cs b/CSS_Solution/Forms/MainForm.cs new file mode 100644 index 0000000..46971a6 --- /dev/null +++ b/CSS_Solution/Forms/MainForm.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Net.Http; +using System.Reflection.Emit; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +namespace CSS_Solution.Forms +{ + + + partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + switch_panels = new List<(Panel, PictureBox)> { (HomePanel,HomePicture),(SetTaskPanel, SetTaskPicture), (RunTaskPanel, RunTaskPicture) ,(SettingsPanel,SettingsPicture)}; + change_form(function_forms[0]); + } + //private void MainForm_Load(object sender, EventArgs e) + //{ + // AllocConsole(); + //} + //[DllImport("kernel32.dll", SetLastError = true)] + //[return: MarshalAs(UnmanagedType.Bool)] + //static extern bool AllocConsole(); + private List
function_forms = new List { new Welcome_Form(), new Change_Task_Form(), new Task_Run_Form(), new Settings_Form() }; + private List<(Panel, PictureBox)> switch_panels; + private void change_form(Form form) + { + FunctionPanel.Controls.Clear(); + form.TopLevel = false; + form.Dock = DockStyle.Fill; + FunctionPanel.Controls.Add(form); + form.Show(); + } + private void SwitchPanels_Click(object sender, EventArgs e) + { + for (int i = 0; i < switch_panels.Count; i++) + { + var (panel, picture) = switch_panels[i]; + + if (panel == sender || picture == sender) + { + change_form(function_forms[i]); + break; + } + } + } + private void SwitchPanels_MouseEnter(object sender, EventArgs e) + { + + } + } +} \ No newline at end of file diff --git a/CSS_Solution/Forms/MainForm.resx b/CSS_Solution/Forms/MainForm.resx new file mode 100644 index 0000000..4546c02 --- /dev/null +++ b/CSS_Solution/Forms/MainForm.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 174, 17 + + \ No newline at end of file diff --git a/CSS_Solution/Forms/Settings_Form.Designer.cs b/CSS_Solution/Forms/Settings_Form.Designer.cs new file mode 100644 index 0000000..8bb9d2f --- /dev/null +++ b/CSS_Solution/Forms/Settings_Form.Designer.cs @@ -0,0 +1,60 @@ +namespace CSS_Solution.Forms +{ + partial class Settings_Form + { + /// + /// 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() + { + label1 = new Label(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.ForeColor = Color.White; + label1.Location = new Point(12, 9); + label1.Name = "label1"; + label1.Size = new Size(22, 24); + label1.TabIndex = 1; + label1.Text = "d"; + // + // Settings_Form + // + AutoScaleDimensions = new SizeF(11F, 24F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(label1); + Name = "Settings_Form"; + Text = "Settings_Form"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label label1; + } +} \ No newline at end of file diff --git a/CSS_Solution/Forms/Settings_Form.cs b/CSS_Solution/Forms/Settings_Form.cs new file mode 100644 index 0000000..701f325 --- /dev/null +++ b/CSS_Solution/Forms/Settings_Form.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CSS_Solution.Forms +{ + public partial class Settings_Form : Form + { + public Settings_Form() + { + InitializeComponent(); + } + } +} diff --git a/CSS_Solution/Forms/Settings_Form.resx b/CSS_Solution/Forms/Settings_Form.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/CSS_Solution/Forms/Settings_Form.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/CSS_Solution/Forms/Task_Run_Form.Designer.cs b/CSS_Solution/Forms/Task_Run_Form.Designer.cs new file mode 100644 index 0000000..b010c9f --- /dev/null +++ b/CSS_Solution/Forms/Task_Run_Form.Designer.cs @@ -0,0 +1,59 @@ +namespace CSS_Solution.Forms +{ + partial class Task_Run_Form + { + /// + /// 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() + { + label1 = new Label(); + SuspendLayout(); + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(12, 9); + label1.Name = "label1"; + label1.Size = new Size(19, 24); + label1.TabIndex = 1; + label1.Text = "c"; + // + // Task_Run_Form + // + AutoScaleDimensions = new SizeF(11F, 24F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(label1); + Name = "Task_Run_Form"; + Text = "Task_Run_Form"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label label1; + } +} \ No newline at end of file diff --git a/CSS_Solution/Forms/Task_Run_Form.cs b/CSS_Solution/Forms/Task_Run_Form.cs new file mode 100644 index 0000000..4150fd0 --- /dev/null +++ b/CSS_Solution/Forms/Task_Run_Form.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CSS_Solution.Forms +{ + public partial class Task_Run_Form : Form + { + public Task_Run_Form() + { + InitializeComponent(); + } + } +} diff --git a/CSS_Solution/Forms/Task_Run_Form.resx b/CSS_Solution/Forms/Task_Run_Form.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/CSS_Solution/Forms/Task_Run_Form.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/CSS_Solution/Forms/Welcome_Form.Designer.cs b/CSS_Solution/Forms/Welcome_Form.Designer.cs new file mode 100644 index 0000000..c469d7a --- /dev/null +++ b/CSS_Solution/Forms/Welcome_Form.Designer.cs @@ -0,0 +1,166 @@ +namespace CSS_Solution.Forms +{ + partial class Welcome_Form + { + /// + /// 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() + { + Welcome = new Label(); + password = new TextBox(); + ID = new TextBox(); + MainPanel = new Panel(); + countdown = new Countdown(); + test = new Button(); + Record = new Button(); + SavePassword = new CheckBox(); + MainPanel.SuspendLayout(); + SuspendLayout(); + // + // Welcome + // + Welcome.AutoSize = true; + Welcome.Font = new Font("Microsoft YaHei UI", 36F, FontStyle.Bold, GraphicsUnit.Point, 134); + Welcome.ForeColor = Color.White; + Welcome.Location = new Point(60, 30); + Welcome.Name = "Welcome"; + Welcome.Size = new Size(737, 96); + Welcome.TabIndex = 0; + Welcome.Text = "Welcome To C.s.s.S"; + // + // password + // + password.BackColor = Color.FromArgb(25, 25, 25); + password.BorderStyle = BorderStyle.FixedSingle; + password.Font = new Font("Microsoft YaHei UI", 15F, FontStyle.Italic, GraphicsUnit.Point, 134); + password.ForeColor = Color.Silver; + password.Location = new Point(86, 271); + password.Name = "password"; + password.Size = new Size(390, 46); + password.TabIndex = 1; + password.Text = "密码..."; + password.Enter += password_Enter; + password.Leave += password_Leave; + // + // ID + // + ID.BackColor = Color.FromArgb(25, 25, 25); + ID.BorderStyle = BorderStyle.FixedSingle; + ID.Font = new Font("Microsoft YaHei UI", 15F, FontStyle.Italic, GraphicsUnit.Point, 134); + ID.ForeColor = Color.Silver; + ID.Location = new Point(86, 186); + ID.Name = "ID"; + ID.Size = new Size(390, 46); + ID.TabIndex = 2; + ID.Text = "学号..."; + ID.Enter += ID_Enter; + ID.Leave += ID_Leave; + // + // MainPanel + // + MainPanel.Controls.Add(countdown); + MainPanel.Controls.Add(test); + MainPanel.Controls.Add(Record); + MainPanel.Controls.Add(SavePassword); + MainPanel.Controls.Add(password); + MainPanel.Controls.Add(Welcome); + MainPanel.Controls.Add(ID); + MainPanel.Dock = DockStyle.Fill; + MainPanel.Location = new Point(0, 0); + MainPanel.Name = "MainPanel"; + MainPanel.Size = new Size(1403, 736); + MainPanel.TabIndex = 3; + // + // countdown + // + countdown.BackColor = Color.FromArgb(25, 25, 25); + countdown.Location = new Point(776, 186); + countdown.Name = "countdown"; + countdown.Size = new Size(395, 222); + countdown.TabIndex = 6; + // + // test + // + test.BackColor = Color.FromArgb(25, 25, 25); + test.ForeColor = Color.White; + test.Location = new Point(269, 393); + test.Name = "test"; + test.Size = new Size(112, 34); + test.TabIndex = 5; + test.Text = "验证密码"; + test.UseVisualStyleBackColor = false; + // + // Record + // + Record.BackColor = Color.FromArgb(25, 25, 25); + Record.ForeColor = Color.White; + Record.Location = new Point(86, 393); + Record.Name = "Record"; + Record.Size = new Size(112, 34); + Record.TabIndex = 4; + Record.Text = "保存密码"; + Record.UseVisualStyleBackColor = false; + // + // SavePassword + // + SavePassword.AutoSize = true; + SavePassword.ForeColor = Color.White; + SavePassword.Location = new Point(86, 337); + SavePassword.Name = "SavePassword"; + SavePassword.Size = new Size(180, 28); + SavePassword.TabIndex = 3; + SavePassword.Text = "保存密码到硬盘?"; + SavePassword.UseVisualStyleBackColor = true; + SavePassword.CheckedChanged += SavePassword_CheckedChanged; + // + // Welcome_Form + // + AutoScaleDimensions = new SizeF(11F, 24F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = Color.FromArgb(25, 25, 25); + ClientSize = new Size(1403, 736); + Controls.Add(MainPanel); + FormBorderStyle = FormBorderStyle.None; + Name = "Welcome_Form"; + Text = "Welcome_Form"; + MainPanel.ResumeLayout(false); + MainPanel.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private Label Welcome; + private TextBox ID; + private TextBox password; + private Panel panel1; + private Panel MainPanel; + private FontDialog fontDialog1; + private CheckBox SavePassword; + private Button Record; + private Button test; + private Countdown countdown; + } +} \ No newline at end of file diff --git a/CSS_Solution/Forms/Welcome_Form.cs b/CSS_Solution/Forms/Welcome_Form.cs new file mode 100644 index 0000000..29c5409 --- /dev/null +++ b/CSS_Solution/Forms/Welcome_Form.cs @@ -0,0 +1,78 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CSS_Solution.Forms +{ + public partial class Welcome_Form : Form + { + public Welcome_Form() + { + InitializeComponent(); + } + private Font normal_font = new Font("Microsoft YaHei UI", 15F, FontStyle.Regular, GraphicsUnit.Point, 134); + private Font italic_font = new Font("Microsoft YaHei UI", 15F, FontStyle.Italic, GraphicsUnit.Point, 134); + private void ID_Enter(object sender, EventArgs e) + { + if (ID.Font != normal_font) + { + ID.Text = string.Empty; + ID.ForeColor = Color.White; + ID.Font = normal_font; + } + } + + private void ID_Leave(object sender, EventArgs e) + { + if (ID.Text == string.Empty) + { + ID.ForeColor = Color.Silver; + ID.Font = italic_font; + ID.Text = "学号..."; + } + } + + private void password_Enter(object sender, EventArgs e) + { + if (password.Font != normal_font) + { + password.Text = string.Empty; + password.ForeColor = Color.White; + password.Font = normal_font; + password.PasswordChar = '*'; + } + } + + private void password_Leave(object sender, EventArgs e) + { + if (password.Text == string.Empty) + { + password.ForeColor = Color.Silver; + password.Font = italic_font; + password.Text = "密码..."; + password.PasswordChar = '\0'; + } + } + bool save_disk_info_showed = false; + private void SavePassword_CheckedChanged(object sender, EventArgs e) + { + + if (sender == null||save_disk_info_showed) + return; + CheckBox? checkBox = sender as CheckBox; + if (checkBox == null) return; + if(checkBox.Checked) + { + save_disk_info_showed = true; + MessageBox.Show("注意,密码确实会保存为密文,但是该密文可直接用于登录网站(教务管理系统),理想状态下,该密码应当仅保存在内存中。"); + } + } + } +} diff --git a/CSS_Solution/Forms/Welcome_Form.resx b/CSS_Solution/Forms/Welcome_Form.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/CSS_Solution/Forms/Welcome_Form.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/CSS_Solution/Program.cs b/CSS_Solution/Program.cs new file mode 100644 index 0000000..4c329e0 --- /dev/null +++ b/CSS_Solution/Program.cs @@ -0,0 +1,111 @@ +using CSS_Solution.Request; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Json; +using Microsoft.Extensions.Logging; +using System; +using System.Linq.Expressions; +using System.Runtime.InteropServices; +using CSS_Solution.Forms; +namespace CSS_Solution +{ + public enum Request_Type + { + get_index, + get_code, + login, + to_course, + change_class + } + public class Initialize + { +#if DEBUG + public static readonly string settings_File_Path = "AppSettings_Debug.json"; +#else + public static readonly string settings_File_Path = "AppSettings.json"; +#endif + public static IConfiguration configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).Add(new JsonConfigurationSource { Path = settings_File_Path, ReloadOnChange = true }).Build(); + public static ILoggerFactory loggerFactory = LoggerFactory.Create(builder => + { + Console.WriteLine(builder); + builder.AddConsole(); + }); + public static ILogger default_logger = loggerFactory.CreateLogger("Default logger"); + public static HttpClientPool hc_pool = new HttpClientPool(); + public Initialize() + { + Program.exceptionHandler = new ExceptionHandler(); + + } + } + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + if (!Init()) + return; +#pragma warning disable CS8604 // 引用类型参数可能为 null。 +#pragma warning disable CS8602 // 解引用可能出现空引用。 + Application.ThreadException += exceptionHandler.ApplicationThreadExceptionHandler; + Initialize.default_logger.LogInformation($"[{DateTime.Now}] log程序和自定义对象初始化完成"); + ApplicationConfiguration.Initialize(); + //#region Test + //{ + // bool cango = false; + // Task_handler.index_Task_Handler.Make_request((t) => { Console.WriteLine(t.ToString()); cango = true; }); + // while (!cango) { } + // cango = false; + // Task_handler.login_Task_Handler.Make_request((t) => { Console.WriteLine(t.ToString()); cango = true; }, null); + // while (!cango) { } + // cango = false; + // Task_handler.toCourse_Task_Handler.Make_request((t) => + // { + // Console.WriteLine(t.ToString()); + // cango = true; + // }, null); + // while (!cango) { } + + + //} + //#endregion + mainForm = new MainForm(); + Application.Run(mainForm); +#pragma warning restore CS8604 // 引用类型参数可能为 null。 +#pragma warning restore CS8602 // 解引用可能出现空引用。 + + } + static bool Init() + { + try + { + new Initialize(); + } + catch (InvalidOperationException e) + { + Console.WriteLine("Initialize failed"); + Console.WriteLine($"[{DateTime.Now}] Message:\n{e.Message}\nStackTrace:\n{e.StackTrace}\n"); + return false; + } + if (exceptionHandler == null) + { + Console.WriteLine("exceptionHandler isn't Initlized"); + return false; + } + if (Initialize.default_logger == null) + { + Console.WriteLine("default_logger isn't Initlized"); + return false; + } + return true; + } + public static MainForm? mainForm; + public static ExceptionHandler? exceptionHandler; + + + } +} \ No newline at end of file diff --git a/CSS_Solution/Properties/Resources.Designer.cs b/CSS_Solution/Properties/Resources.Designer.cs new file mode 100644 index 0000000..2b5fe7e --- /dev/null +++ b/CSS_Solution/Properties/Resources.Designer.cs @@ -0,0 +1,103 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace CSS_Solution.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CSS_Solution.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap home { + get { + object obj = ResourceManager.GetObject("home", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap input { + get { + object obj = ResourceManager.GetObject("input", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Run { + get { + object obj = ResourceManager.GetObject("Run", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap settings { + get { + object obj = ResourceManager.GetObject("settings", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/CSS_Solution/Properties/Resources.resx b/CSS_Solution/Properties/Resources.resx new file mode 100644 index 0000000..e79d0e2 --- /dev/null +++ b/CSS_Solution/Properties/Resources.resx @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + ..\Resources\home.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\input.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Run.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/CSS_Solution/Request/Course_Request.cs b/CSS_Solution/Request/Course_Request.cs new file mode 100644 index 0000000..c53e0e1 --- /dev/null +++ b/CSS_Solution/Request/Course_Request.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSS_Solution.Request +{ + internal class Course_Request + { + } +} diff --git a/CSS_Solution/Request/Get_Index.cs b/CSS_Solution/Request/Get_Index.cs new file mode 100644 index 0000000..006d09e --- /dev/null +++ b/CSS_Solution/Request/Get_Index.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HtmlAgilityPack; +using Microsoft.Extensions.Configuration; +using HtmlDocument = HtmlAgilityPack.HtmlDocument; + +namespace CSS_Solution.Request +{ + internal class Get_Index : IRequest + { + Task task; + readonly int id; + string rnd = ""; + string? url; + Action success; + Action failed; + List> respond_cookie = new List>(); + public Request_Type request_type { get; } = Request_Type.get_index; + public Get_Index(int _id, Action _success, Action _failed) + { + id = _id; + success = _success; + failed = _failed; + url = Initialize.configuration?.GetSection("login_index").Value; + if (url == null || url.Length == 0) + throw new ConfigurationErrorsException("Can't get login_index url from AppSettings.json"); + task = new Task(async () => + { + try + { + HttpClient client = Initialize.hc_pool.getHttpClient(request_type); + HttpRequestMessage request_Message = new HttpRequestMessage(HttpMethod.Get, url); + List<(string, string)> request_header = Settings.get_Index_Header.Get_header(); + foreach (var (key, value) in request_header) + request_Message.Headers.Add(key, value); + HttpResponseMessage message = await client.SendAsync(request_Message); + message.EnsureSuccessStatusCode(); + HtmlDocument htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(await message.Content.ReadAsStringAsync()); + var node = htmlDoc.DocumentNode.SelectSingleNode("//input[@id='rnd']"); + rnd = node.GetAttributeValue("value", ""); + foreach (var header in message.Headers) + { + if (header.Key != "Set-Cookie") + continue; + foreach (var item in header.Value) + foreach (var item1 in item.Split("; ")) + { + string[] Key_ValuePair = item1.Split('='); + respond_cookie.Add(new KeyValuePair(Key_ValuePair[0], Key_ValuePair[1])); + } + } + } + catch (Exception ex) + { + failed(id, ex, null); + } + success(id); + }); + } + public List>? Get_cookie() + { + if (!task.IsCompleted) + return null; + return respond_cookie; + } + public string? Get_rnd() => rnd; + public int Get_Id() => id; + public Task Run() + { + task.Start(); + return task; + } + + } +} diff --git a/CSS_Solution/Request/HttpClientPool.cs b/CSS_Solution/Request/HttpClientPool.cs new file mode 100644 index 0000000..5b0020b --- /dev/null +++ b/CSS_Solution/Request/HttpClientPool.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSS_Solution.Request +{ + public class HttpClientPool + { + HttpClient[] httpClients = new HttpClient[5]; + public HttpClientPool() + { + for (int i = 0; i < httpClients.Length; i++) + if(i==(int)Request_Type.to_course) + httpClients[i] = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = false }); + else + httpClients[i] = new HttpClient(); + } + public HttpClient getHttpClient(Request_Type request_Type) => httpClients[(int)request_Type]; + } + + +} diff --git a/CSS_Solution/Request/IRequest.cs b/CSS_Solution/Request/IRequest.cs new file mode 100644 index 0000000..621f64e --- /dev/null +++ b/CSS_Solution/Request/IRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSS_Solution.Request +{ + internal interface IRequest + { + List>? Get_cookie(); + public Request_Type request_type { get; } + + } +} diff --git a/CSS_Solution/Request/Login.cs b/CSS_Solution/Request/Login.cs new file mode 100644 index 0000000..8531e39 --- /dev/null +++ b/CSS_Solution/Request/Login.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; +using System.Net.Http.Headers; + +namespace CSS_Solution.Request +{ + internal class Login : IRequest + { + Action success; + Action failed; + string? getCode_url; + string? login_url; + string? code; + string? JSESSIONID; + Task task; + List> respond_cookie = new List>(); + readonly int id; + public Request_Type request_type => Request_Type.login; + public Login(int _id, Get_Index_Result last_result, Action _success, Action _failed) + { + id = _id; + success = _success; + failed = _failed; + getCode_url = Initialize.configuration?.GetSection("getcode").Value; + if (getCode_url == null || getCode_url.Length == 0) + throw new ConfigurationErrorsException("Can't get getcode url from AppSettings.json"); + login_url = Initialize.configuration?.GetSection("login_index").Value; + if (login_url == null || login_url.Length == 0) + throw new ConfigurationErrorsException("Can't get login_index url from AppSettings.json"); + if (last_result.RND == null || last_result.JSESSIONID == null) + throw new InvalidOperationException("Something wrong with Get_Index result"); + JSESSIONID = last_result.JSESSIONID; + task = new Task(async () => + { + try + { + { + HttpClient client = Initialize.hc_pool.getHttpClient(Request_Type.get_code); + HttpRequestMessage code_request_Message = new HttpRequestMessage(HttpMethod.Post, getCode_url); + code_request_Message.Headers.Add("Cookie", JSESSIONID); + foreach (var (key, value) in Settings.getCode_Header.Get_Request_header()) + code_request_Message.Headers.Add(key, value); + code_request_Message.Content = new FormUrlEncodedContent([new KeyValuePair("webfinger", Settings.webfinger.Get_webfinger().Item2)]); + code_request_Message.Content.Headers.ContentType = new MediaTypeHeaderValue(Settings.getCode_Header.Content_Type); + code_request_Message.Content.Headers.ContentLength = int.Parse(Settings.getCode_Header.Content_Length); + HttpResponseMessage code_message = await client.SendAsync(code_request_Message); + code_message.EnsureSuccessStatusCode(); + code = await code_message.Content.ReadAsStringAsync(); + } + { + HttpClient client = Initialize.hc_pool.getHttpClient(request_type); + HttpRequestMessage login_request_Message = new HttpRequestMessage(HttpMethod.Post, login_url); + login_request_Message.Headers.Add("Cookie", JSESSIONID); + foreach (var (key, value) in Settings.login_Header.Get_Request_header()) + login_request_Message.Headers.Add(key, value); + List> response_body = Settings.login_Body.Get_Request_body(last_result.RND, code); + login_request_Message.Content = new FormUrlEncodedContent(response_body); + login_request_Message.Content.Headers.ContentType = new MediaTypeHeaderValue(Settings.login_Header.Content_Type); + HttpResponseMessage message = await client.SendAsync(login_request_Message); + message.EnsureSuccessStatusCode(); + string ans = await message.Content.ReadAsStringAsync(); + + foreach (var header in message.Headers) + { + if (header.Key != "Set-Cookie") + continue; + foreach (var item in header.Value) + foreach (var item1 in item.Split("; ")) + { + string[] Key_ValuePair = item1.Split('='); + if (Key_ValuePair.Length != 2) + continue; + respond_cookie.Add(new KeyValuePair(Key_ValuePair[0], Key_ValuePair[1])); + } + } + } + } + catch (Exception ex) + { + failed(id, ex, null); + } + success(id); + }); + } + public List>? Get_cookie() + { + return respond_cookie; + } + public Task Run() + { + task.Start(); + return task; + } + + internal int Get_Id() => id; + public string Get_JSESSIONID() => JSESSIONID ?? ""; + } +} diff --git a/CSS_Solution/Request/RequestResults.cs b/CSS_Solution/Request/RequestResults.cs new file mode 100644 index 0000000..3fec18a --- /dev/null +++ b/CSS_Solution/Request/RequestResults.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSS_Solution.Request +{ + class Get_Index_Result + { + public int? id; + public string? JSESSIONID; + public string? RND; + public DateTime dateTime; + private string? error_info; + public string Error_info + { + get { return error_info ??= ""; } + set + { + error_info = value; + is_error = true; + } + } + bool is_error; + public Get_Index_Result(int _id, string jSESSIONID, string rND, DateTime dateTime) + { + id = _id; + JSESSIONID = jSESSIONID; + RND = rND; + error_info = ""; + this.dateTime = dateTime; + } + public Get_Index_Result(Get_Index get_Index) + { + id = get_Index.Get_Id(); + JSESSIONID = get_Index.Get_cookie()?.Select(element => new { element.Key, element.Value }).Where(element => element.Key.Equals("JSESSIONID")).First().Value; + RND = get_Index.Get_rnd(); + dateTime = DateTime.Now; + error_info = ""; + } + public Get_Index_Result(string error_info) => Error_info = error_info; + public bool Wrong_Result() => JSESSIONID == null || RND == null; + public bool isError() => is_error; + } + class Login_Result + { + public List> cookie = new List>(); + public int? id; + public string? JSESSIONID; + public string? CERLOGIN; + public DateTime dateTime; + private string? error_info; + public string Error_info + { + get { return error_info ??= ""; } + set + { + error_info = value; + is_error = true; + } + } + bool is_error; + + public Login_Result(int _id, string jSESSIONID, string cERLOGIN, DateTime dateTime) + { + id = _id; + JSESSIONID = jSESSIONID; + CERLOGIN = cERLOGIN; + dateTime = DateTime.Now; + error_info = ""; + cookie = new List>(); + cookie.Add(new KeyValuePair("JSESSIONID", JSESSIONID)); + cookie.Add(new KeyValuePair("CERLOGIN", CERLOGIN)); + } + public Login_Result(Login login) + { + id = login.Get_Id(); + cookie = login.Get_cookie() ?? throw new InvalidOperationException("Cookie of Login is NULL?!"); + for (int i = 0; i < cookie.Count; i++) + if (cookie[i].Key == "JSESSIONID" || cookie[i].Key == "Path") + { + cookie.RemoveAt(i); + i--; + } + JSESSIONID = login.Get_JSESSIONID(); + CERLOGIN = cookie?.Select(x => x).Where(element => element.Key.Equals("CERLOGIN")).First().Value; + cookie?.Add(new KeyValuePair("JSESSIONID", JSESSIONID)); + dateTime = DateTime.Now; + error_info = ""; + } + public Login_Result(string error_info) => Error_info = error_info; + public bool Wrong_Result() => JSESSIONID == null || CERLOGIN == null || cookie.Select(x => new { havenull = x.Value == null }).Where(x => x.havenull).Count() > 0; + public bool isError() => is_error; + public List> Get_cookie() => cookie; + } + class To_Course_Result + { + public List> cookie = new List>(); + public int? id; + public string? JSESSIONID; + public string? BINGOCLOUDLB; + public DateTime dateTime; + private string? error_info; + public string Error_info + { + get { return error_info ??= ""; } + set + { + error_info = value; + is_error = true; + } + } + bool is_error; + public To_Course_Result(int _id,string jSESSIONID,string bINGOCLOUDLB,DateTime dateTime) + { + id = _id; + JSESSIONID = jSESSIONID; + BINGOCLOUDLB = bINGOCLOUDLB; + error_info = ""; + this.dateTime = dateTime; + } + public To_Course_Result(To_Course to_Course) + { + id = to_Course.get_ID(); + cookie = to_Course.Get_cookie() ?? throw new InvalidOperationException("Cookie of ToCourse is NULL?!"); + JSESSIONID = cookie?.Select(x => x).Where(element => element.Key.Equals("JSESSIONID")).First().Value; + BINGOCLOUDLB = cookie?.Select(x => x).Where(element => element.Key.Equals("BINGOCLOUDLB")).First().Value; + dateTime = DateTime.Now; + error_info = ""; + } + public To_Course_Result(string error_info) => Error_info = error_info; + public bool Wrong_Result() => JSESSIONID == null || BINGOCLOUDLB == null || cookie.Select(x => new { havenull = x.Value == null }).Where(x => x.havenull).Count() > 0; + public bool isError() => is_error; + public List> Get_cookie() => cookie; + + } +} diff --git a/CSS_Solution/Request/Task_handler.cs b/CSS_Solution/Request/Task_handler.cs new file mode 100644 index 0000000..fc5abe2 --- /dev/null +++ b/CSS_Solution/Request/Task_handler.cs @@ -0,0 +1,181 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CSS_Solution.Request +{ + class Task_handler + { + public static Index_Task_handler index_Task_Handler = new Index_Task_handler(); + public static Login_Task_handler login_Task_Handler = new Login_Task_handler(); + public static ToCourse_Task_Handler toCourse_Task_Handler = new ToCourse_Task_Handler(); + } + class Index_Task_handler + { + int current_id = 0; + public LinkedList results = new LinkedList(); + Dictionary)> tasks = new Dictionary)>(); + public void Make_request(Action result_handler) + { + current_id++; + Get_Index get_Index = new Get_Index(current_id, GetIndex_success, GetIndex_failed); + get_Index.Run(); + tasks.Add(current_id, (get_Index, result_handler)); + } + public void GetIndex_success(int id) + { + Action result_handler; + Get_Index_Result result; + if (tasks.TryGetValue(id, out (Get_Index, Action) value)) + { + Get_Index task = value.Item1; + result_handler = value.Item2; + result = new Get_Index_Result(task); + if (result.Wrong_Result()) + { + GetIndex_failed(id, new HttpRequestException("Get_Index Result info error, Check it out!"), result); + return; + } + results.AddFirst(result); + } + else + { + GetIndex_failed(id, new KeyNotFoundException($"Get_Index: who called me? I even don't have ID {id}")); + return; + } + tasks.Remove(id); + result_handler(result); + } + public void GetIndex_failed(int id, Exception e, Get_Index_Result? result = null) + { + if (e.GetType() == typeof(KeyNotFoundException)) + { + Initialize.default_logger.LogWarning($"[{DateTime.Now}] ToIndex: {e.Message}"); + return; + } + if (result == null) + result = new Get_Index_Result(e.Message); + else + result.Error_info = e.Message; + tasks[id].Item2(result); + tasks.Remove(id); + } + public Get_Index_Result Newest_Result() => results.First(); + } + class Login_Task_handler + { + int current_id = 0; + public LinkedList results = new LinkedList(); + Dictionary)> tasks = new Dictionary)>(); + public void Make_request(Action result_handler, Get_Index_Result? last_result) + { + current_id++; + last_result ??= Task_handler.index_Task_Handler.Newest_Result(); + if (last_result == null) + throw new InvalidOperationException("No usable Get_Index_Result for Login"); + Login login = new Login(current_id, last_result, Login_success, Login_failed); + login.Run(); + tasks.Add(current_id, (login, result_handler)); + } + public void Login_success(int id) + { + Action result_handler; + Login_Result result; + if (tasks.TryGetValue(id, out (Login, Action) value)) + { + Login task = value.Item1; + result_handler = value.Item2; + result = new Login_Result(task); + if (result.Wrong_Result()) + { + Login_failed(id, new HttpRequestException("Login Result info error, Check it out!"), result); + return; + } + results.AddFirst(result); + } + else + { + Login_failed(id, new KeyNotFoundException($"Login: who called me? I even don't have ID {id}")); + return; + } + tasks.Remove(id); + result_handler(result); + } + public void Login_failed(int id, Exception e, Login_Result? result = null) + { + if (e.GetType() == typeof(KeyNotFoundException)) + { + Initialize.default_logger.LogWarning($"[{DateTime.Now}] Login: {e.Message}"); + return; + } + if (result == null) + result = new Login_Result(e.Message); + else + result.Error_info = e.Message; + tasks[id].Item2(result); + tasks.Remove(id); + } + public List>? Newest_cookie() => results.First()?.cookie; + public Login_Result Newest_result() => results.First(); + } + class ToCourse_Task_Handler + { + int current_id = 0; + public LinkedListresults = new LinkedList(); + Dictionary)> tasks = new Dictionary)>(); + public void Make_request(Action result_handler,Login_Result? last_result) + { + current_id++; + last_result ??=Task_handler.login_Task_Handler.Newest_result(); + if(last_result == null) + throw new InvalidOperationException("No usable Login_Result for Login"); + To_Course to_Course = new To_Course(current_id, last_result,To_Course_success,To_Course_failed); + to_Course.Run(); + tasks.Add(current_id, (to_Course, result_handler)); + } + public void To_Course_success(int id) + { + Action result_handler; + To_Course_Result result; + if(tasks.TryGetValue(id,out (To_Course,Action) value)) + { + To_Course task = value.Item1; + result_handler = value.Item2; + result = new To_Course_Result(task); + if(result.Wrong_Result()) + { + To_Course_failed(id, new HttpRequestException("To_Course Result info error, Check it out!"), result); + return; + } + results.AddLast(result); + } + else + { + To_Course_failed(id, new KeyNotFoundException($"To_Course: who called me? I even don't have ID {id}")); + return; + } + tasks.Remove(id); + result_handler(result); + } + + public void To_Course_failed(int id,Exception e,To_Course_Result? result = null) + { + if (e.GetType() == typeof(KeyNotFoundException)) + { + Initialize.default_logger.LogWarning($"[{DateTime.Now}] Login: {e.Message}"); + return; + } + if(result==null) + result = new To_Course_Result(e.Message); + else + result.Error_info = e.Message; + tasks[id].Item2(result); + tasks.Remove(id); + + } + + } +} diff --git a/CSS_Solution/Request/To_Course.cs b/CSS_Solution/Request/To_Course.cs new file mode 100644 index 0000000..7e7df3a --- /dev/null +++ b/CSS_Solution/Request/To_Course.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace CSS_Solution.Request +{ + internal class To_Course : IRequest + { + Task task; + readonly int id; + string? url; + string? Referer; + Action success; + Action failed; + List> respond_cookie = new List>(); + string? Course_cookie, Certification_cookie; + public Request_Type request_type => Request_Type.to_course; + public To_Course(int _id, Login_Result last_result, Action _success, Action _failed) + { + id = _id; + success = _success; + failed = _failed; + url = Initialize.configuration?.GetSection("to_course").Value; + if (url == null || url.Length == 0) + throw new ConfigurationErrorsException("Can't get to_course url from AppSettings.json"); + task = new Task(async () => + { + try + { + Func Get_HttpRequestMessage = (string? url) => + { + if (url == null || url.Length == 0) + throw new ConfigurationErrorsException("The url for Request is null"); + HttpRequestMessage request_Message = new HttpRequestMessage(HttpMethod.Post, url); + request_Message.Headers.Add("Cookie", "CERLOGIN" + "=" + last_result.CERLOGIN + "; BINGOCLOUDLB=f2adbbd5386222824901cc921da810f4"); + foreach (var (key, value) in Settings.to_Course_Header.Get_header()) + request_Message.Headers.Add(key, value); + return request_Message; + }; + HttpClient client = Initialize.hc_pool.getHttpClient(request_type); + HttpResponseMessage message; + do + { + message = await client.SendAsync(Get_HttpRequestMessage(url)); + foreach (var header in message.Headers) + { + if (header.Key != "Set-Cookie") + continue; + foreach (var item in header.Value) + foreach (var item1 in item.Split("; ")) + { + string[] Key_ValuePair = item1.Split('='); + if (Key_ValuePair.Length != 2) + continue; + respond_cookie.Add(new KeyValuePair(Key_ValuePair[0], Key_ValuePair[1])); + } + } + url = message?.Headers?.Location?.ToString() ?? url; + if (message == null) + throw new Exception("Internet Error, response is null."); + } while (message.StatusCode == HttpStatusCode.Redirect); + message.EnsureSuccessStatusCode(); + foreach (var header in message.Headers) + { + if (header.Key != "Set-Cookie") + continue; + foreach (var item in header.Value) + foreach (var item1 in item.Split("; ")) + { + string[] Key_ValuePair = item1.Split('='); + if (Key_ValuePair.Length != 2) + continue; + respond_cookie.Add(new KeyValuePair(Key_ValuePair[0], Key_ValuePair[1])); + } + } + //Need Del + string ans = await message.Content.ReadAsStringAsync(); + string s = await message.Content.ReadAsStringAsync(); + } + catch (Exception ex) + { + failed(id, ex, null); + } + Cookie_parse(); + Referer = url; + + success(id); + }); + } + private void Cookie_parse() + { + for (int i = 0; i < respond_cookie.Count ; i++) + { + if (respond_cookie[i].Key == "Path") + { + if (respond_cookie[i].Value == "/Course") + Course_cookie = respond_cookie[i - 1].Value; + if (respond_cookie[i].Value == "/Certification") + Certification_cookie = respond_cookie[i - 1].Value; + } + } + } + public List>? Get_cookie() + { + if (!task.IsCompleted) + return null; + return respond_cookie; + } + + public int get_ID() => id; + public Task Run() + { + task.Start(); + return task; + } + } +} diff --git a/CSS_Solution/Resources/Run.png b/CSS_Solution/Resources/Run.png new file mode 100644 index 0000000000000000000000000000000000000000..2c47f8ce23fb7ff50e0afad01eb3790c715ffbac GIT binary patch literal 4827 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 J2MP^){~N?IvBm%Z literal 0 HcmV?d00001 diff --git a/CSS_Solution/Resources/home.png b/CSS_Solution/Resources/home.png new file mode 100644 index 0000000000000000000000000000000000000000..769b47bc8fd0c8bbda67cb94c53b741b3fdbbfd4 GIT binary patch literal 7345 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 literal 0 HcmV?d00001 diff --git a/CSS_Solution/Resources/input.png b/CSS_Solution/Resources/input.png new file mode 100644 index 0000000000000000000000000000000000000000..0f782227772bab9ccf7628266a20cecc7fb7af94 GIT binary patch literal 5110 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 literal 0 HcmV?d00001 diff --git a/CSS_Solution/Settings.cs b/CSS_Solution/Settings.cs new file mode 100644 index 0000000..c40170b --- /dev/null +++ b/CSS_Solution/Settings.cs @@ -0,0 +1,345 @@ +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Net.Mime; +using System.Reflection; +using System.Reflection.Metadata; +using System.Text; +using System.Text.Encodings.Web; +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; +namespace CSS_Solution +{ + public class Settings + { + + public static Get_Index_header get_Index_Header = new Get_Index_header(); + public static GetCode_header getCode_Header = new GetCode_header(); + public static Webfinger webfinger = new Webfinger(); + public static Login_header login_Header = new Login_header(); + public static Login_body login_Body = new Login_body(); + public static To_Course_header to_Course_Header = new To_Course_header(); + public static Etc etc = new Etc(); + } + public class Get_Index_header + { + List<(string, string)> header = new List<(string, string)>(); + public Get_Index_header() + { + User_Agent = ""; + Accept = ""; + Host = ""; + Accept_Encoding = ""; + Connection = ""; + Initialize.configuration.Bind("getIndex_headers", this); + } + public List<(string, string)> Get_header() + { + if (header.Count != 0) + return header; + Type type = typeof(Get_Index_header); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (PropertyInfo property in propertyInfo) + { + var val = (property.Name, property.GetValue(this) as string); + if (val.Item2 == null) + throw new ConfigurationErrorsException("Default header get error"); + header.Add((val.Item1.Replace('_', '-'), val.Item2)); + } + return header; + } + public string User_Agent { get; set; } + public string Accept { get; set; } + public string Host { get; set; } + public string Accept_Encoding { get; set; } + public string Connection { get; set; } + } + public class GetCode_header + { + List<(string, string)> header = new List<(string, string)>(); + public GetCode_header() + { + User_Agent = ""; + Accept = ""; + Host = ""; + Accept_Encoding = ""; + Connection = ""; + Content_Type = ""; + Content_Length = ""; + Initialize.configuration.Bind("getCode_headers", this); + } + public List<(string, string)> Get_Request_header() + { + if (header.Count != 0) + return header; + Type type = typeof(GetCode_header); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (PropertyInfo property in propertyInfo) + { + var val = (property.Name, property.GetValue(this) as string); + if (val.Name == "Content_Type" || val.Name == "Content_Length") + continue; + if (val.Item2 == null) + throw new ConfigurationErrorsException("Default header get error"); + header.Add((val.Item1.Replace('_', '-'), val.Item2)); + } + return header; + } + public string User_Agent { get; set; } + public string Accept { get; set; } + public string Host { get; set; } + public string Accept_Encoding { get; set; } + public string Connection { get; set; } + public string Content_Type { get; set; } + public string Content_Length { get; set; } + } + public class Webfinger + { + public string webfinger { get; set; } + public Webfinger() + { + webfinger = ""; + Initialize.configuration.Bind("getcode_body", this); + } + public (string, string) Get_webfinger() => ("webfinger", webfinger); + } + public class Login_header + { + List> header = new List>(); + public Login_header() + { + Accept = ""; + Accept_Encoding = ""; + Accept_Language = ""; + Cache_Control = ""; + Content_Length = ""; + Content_Type = ""; + Host = ""; + Origin = ""; + Referer = ""; + Upgrade_Insecure_Requests = ""; + Keep_Alive = ""; + User_Agent = ""; + Connection = ""; + Initialize.configuration.Bind("login_header", this); + + } + + public List> Get_Request_header() + { + if (header.Count != 0) + return header; + Type type = typeof(Login_header); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (PropertyInfo property in propertyInfo) + { + var val = (property.Name, property.GetValue(this) as string); + if (val.Name == "Content_Type" || val.Name == "Content_Length") + continue; + if (val.Item2 == null) + throw new ConfigurationErrorsException("Default header get error"); + header.Add(new KeyValuePair(val.Item1.Replace('_', '-'), val.Item2)); + } + return header; + } + public string Accept { get; set; } + public string Accept_Encoding { get; set; } + public string Accept_Language { get; set; } + public string Cache_Control { get; set; } + public string Content_Length { get; set; } + public string Content_Type { get; set; } + public string Host { get; set; } + public string Origin { get; set; } + public string Referer { get; set; } + public string Upgrade_Insecure_Requests { get; set; } + public string Keep_Alive { get; set; } + public string User_Agent { get; set; } + public string Connection { get; set; } + + + } + public class Login_body + { + List> body = new List>(); + public Login_body() + { + MsgID = ""; + KeyID = ""; + UserName = ""; + Password = ""; + rnd = ""; + return_EncData = ""; + code = ""; + userName1 = ""; + password1 = ""; + webfinger = ""; + falg = ""; + type = ""; + userName_ = ""; + password_ = ""; + Initialize.configuration.Bind("login_body", this); + } + public List> Get_Request_body(string rnd, string code) + { + if (body.Count != 0) + return body; + Type type = typeof(Login_body); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (PropertyInfo property in propertyInfo) + { + var val = (property.Name, property.GetValue(this) as string); + if (val.Name == "rnd") + { + body.Add(new KeyValuePair(val.Name, rnd)); + continue; + } + if (val.Name == "code") + { + body.Add(new KeyValuePair(val.Name, code)); + continue; + } + if (val.Item2 == null) + throw new ConfigurationErrorsException("Default header get error"); + body.Add(new KeyValuePair(val.Name.Last() == '_' ? val.Name.Remove(val.Name.Length - 1) : val.Name, val.Item2)); + } + return body; + } + public string MsgID { get; set; } + public string KeyID { get; set; } + public string UserName { get; set; } + public string Password { get; set; } + public string rnd { get; set; } + public string return_EncData { get; set; } + public string code { get; set; } + public string userName1 { get; set; } + public string password1 { get; set; } + public string webfinger { get; set; } + public string falg { get; set; } + public string type { get; set; } + public string userName_ { get; set; } + public string password_ { get; set; } + } + public class To_Course_header + { + List<(string, string)> header = new List<(string, string)>(); + public To_Course_header() + { + User_Agent = ""; + Accept = ""; + Accept_Encoding = ""; + Accept_Language = ""; + Referer = ""; + Upgrade_Insecure_Requests = ""; + Connection = ""; + Initialize.configuration.Bind("to_course_header", this); + } + public List<(string, string)> Get_header() + { + if (header.Count != 0) + return header; + Type type = typeof(To_Course_header); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (PropertyInfo property in propertyInfo) + { + var val = (property.Name, property.GetValue(this) as string); + if (val.Item2 == null) + throw new ConfigurationErrorsException("Default header get error"); + header.Add((val.Item1.Replace('_', '-'), val.Item2)); + } + return header; + } + public string User_Agent { get; set; } + public string Accept { get; set; } + public string Accept_Encoding { get; set; } + public string Accept_Language { get; set; } + public string Referer { get; set; } + public string Upgrade_Insecure_Requests { get; set; } + public string Connection { get; set; } + } + public class Course_Request_Url + { + + public string? jxjhh { get; set; }//教学计划号 + public string? xnxq { get; set; }//学年学期 + public string? kcdm { get; set; }//课程代码 + public string? flag { get; set; }//可选参数 flag + public string? temp { get; set; }//可选参数temp + public string? addid { get; set; }//选课时addid + public string? keyinfo { get; set; }//选课时keyinfo + public string? _ { get; set; }//时间戳 + public Course_Request_Url(string? jxjhh, string? xnxq, string? kcdm, string? flag, string? temp, string? addid, string? keyinfo) + { + this.jxjhh = jxjhh; + + this.xnxq = xnxq; + this.kcdm = kcdm; + this.flag = flag; + this.temp = temp; + this.addid = addid; + this.keyinfo = keyinfo; + _ = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond).ToString(); + } + + } + public class Etc + { + public Etc() + { + StartTime_Str = ""; + Initialize.configuration.Bind("Etc", this); + if (StartTime_Str.Length == 0) + StartTime = DateTime.Now; + try + { + string[] strs = StartTime_Str.Split('-'); + int[] arguments = strs.Select(x => int.Parse(x)).ToArray(); + if (arguments.Length != 6) + throw new InvalidOperationException("No Enough Argument"); + StartTime = new DateTime(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]); + } + catch (Exception) + { + StartTime = DateTime.Now; + } + } + public string StartTime_Str { get; set; } + public DateTime StartTime { get; set; } + public void Set_StartTime(int year, int month, int day, int hour, int minute, int second) + { + StartTime = new DateTime(year, month, day, hour, minute, second); + StartTime_Str = year.ToString() + "-" + month.ToString() + "-" + day.ToString() + "-" + hour.ToString() + "-" + minute.ToString() + "-" + second.ToString(); + } + public void Write_StartTime_To_File() + { + string filePath = Initialize.settings_File_Path; + using (StreamReader fileReader = File.OpenText(filePath)) + { + using (JsonTextReader reader = new JsonTextReader(fileReader)) + { + JObject jsonObject = (JObject)JToken.ReadFrom(reader); +#pragma warning disable CS8602 // 解引用可能出现空引用。 + jsonObject["Etc"]["StartTime_Str"] = "StartTime_Str"; +#pragma warning restore CS8602 // 解引用可能出现空引用。 + fileReader.BaseStream.Seek(0, SeekOrigin.Begin); + fileReader.DiscardBufferedData(); + using (StreamWriter fileWriter = File.CreateText(filePath)) + { + using (JsonTextWriter writer = new JsonTextWriter(fileWriter)) + { + writer.Formatting = Formatting.Indented; + jsonObject.WriteTo(writer); + writer.Flush(); + } + } + } + } + } + } + +}