Commit d761b63c authored by tr's avatar tr

1、实施工具:增加日志查看器(初版)

parent 488e94a9
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<appSettings> <appSettings>
<add key="UpdateTime" value="2021-09-16 14:24:34.777" /> <add key="UpdateTime" value="2021-09-16 14:39:31.333" />
</appSettings> </appSettings>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
......
...@@ -205,7 +205,7 @@ namespace Tools.MyUtils ...@@ -205,7 +205,7 @@ namespace Tools.MyUtils
} }
#endregion #endregion
#region 选择文件 #region 选择文件/路径
/// <summary> /// <summary>
/// 选择文件 /// 选择文件
...@@ -230,6 +230,25 @@ namespace Tools.MyUtils ...@@ -230,6 +230,25 @@ namespace Tools.MyUtils
} }
return result; return result;
} }
/// <summary>
/// 选择文件夹
/// </summary>
/// <returns></returns>
public static string SelectFolder()
{
var result = "";
var dlg = new FolderBrowserDialog()
{
Description = "请选择日志目录",
RootFolder = Environment.SpecialFolder.Desktop,
ShowNewFolderButton = false,
};
if (dlg.ShowDialog() == DialogResult.OK)
{
result = dlg.SelectedPath;
}
return result;
}
#endregion #endregion
#region 检查文件大小 #region 检查文件大小
......
...@@ -290,6 +290,16 @@ namespace Tools.Properties { ...@@ -290,6 +290,16 @@ namespace Tools.Properties {
} }
} }
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap 文件夹 {
get {
object obj = ResourceManager.GetObject("文件夹", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary> /// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。 /// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary> /// </summary>
......
...@@ -187,6 +187,9 @@ ...@@ -187,6 +187,9 @@
<data name="数据库" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="数据库" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\数据库.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\数据库.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="文件夹" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\文件夹.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="新增" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="新增" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\新增.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\新增.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
......
...@@ -245,6 +245,12 @@ ...@@ -245,6 +245,12 @@
<Compile Include="UI\wLoginPwd.Designer.cs"> <Compile Include="UI\wLoginPwd.Designer.cs">
<DependentUpon>wLoginPwd.cs</DependentUpon> <DependentUpon>wLoginPwd.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="UI\wLogViewer.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="UI\wLogViewer.Designer.cs">
<DependentUpon>wLogViewer.cs</DependentUpon>
</Compile>
<Compile Include="UI\wModuleManager.cs"> <Compile Include="UI\wModuleManager.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
...@@ -379,6 +385,9 @@ ...@@ -379,6 +385,9 @@
<EmbeddedResource Include="UI\wLoginPwd.resx"> <EmbeddedResource Include="UI\wLoginPwd.resx">
<DependentUpon>wLoginPwd.cs</DependentUpon> <DependentUpon>wLoginPwd.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="UI\wLogViewer.resx">
<DependentUpon>wLogViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\wModuleManager.resx"> <EmbeddedResource Include="UI\wModuleManager.resx">
<DependentUpon>wModuleManager.cs</DependentUpon> <DependentUpon>wModuleManager.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
...@@ -498,6 +507,7 @@ ...@@ -498,6 +507,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="favior.ico" /> <Content Include="favior.ico" />
<None Include="Resources\文件夹.png" />
<None Include="Resources\nav_plain_red.png" /> <None Include="Resources\nav_plain_red.png" />
<None Include="Resources\nav_plain_green.png" /> <None Include="Resources\nav_plain_green.png" />
<None Include="Resources\nav_left_green.png" /> <None Include="Resources\nav_left_green.png" />
......
namespace Tools.UI
{
partial class wLogViewer
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
this.tstbLogPath = new System.Windows.Forms.ToolStripTextBox();
this.tsbSelectPath = new System.Windows.Forms.ToolStripButton();
this.listBox1 = new System.Windows.Forms.ListBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.toolStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.SuspendLayout();
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripLabel1,
this.tstbLogPath,
this.tsbSelectPath});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(695, 25);
this.toolStrip1.TabIndex = 0;
this.toolStrip1.Text = "toolStrip1";
//
// toolStripLabel1
//
this.toolStripLabel1.Name = "toolStripLabel1";
this.toolStripLabel1.Size = new System.Drawing.Size(68, 22);
this.toolStripLabel1.Text = "日志路径:";
//
// tstbLogPath
//
this.tstbLogPath.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F);
this.tstbLogPath.Name = "tstbLogPath";
this.tstbLogPath.ReadOnly = true;
this.tstbLogPath.Size = new System.Drawing.Size(300, 25);
//
// tsbSelectPath
//
this.tsbSelectPath.Image = global::Tools.Properties.Resources.文件夹;
this.tsbSelectPath.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsbSelectPath.Name = "tsbSelectPath";
this.tsbSelectPath.Size = new System.Drawing.Size(76, 22);
this.tsbSelectPath.Text = "选择路径";
//
// listBox1
//
this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listBox1.FormattingEnabled = true;
this.listBox1.ItemHeight = 12;
this.listBox1.Location = new System.Drawing.Point(0, 0);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(156, 425);
this.listBox1.TabIndex = 1;
//
// textBox1
//
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBox1.Location = new System.Drawing.Point(0, 0);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.textBox1.Size = new System.Drawing.Size(535, 423);
this.textBox1.TabIndex = 2;
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 25);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.listBox1);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.textBox1);
this.splitContainer1.Panel2.Controls.Add(this.progressBar1);
this.splitContainer1.Size = new System.Drawing.Size(695, 425);
this.splitContainer1.SplitterDistance = 156;
this.splitContainer1.TabIndex = 3;
//
// progressBar1
//
this.progressBar1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.progressBar1.Location = new System.Drawing.Point(0, 423);
this.progressBar1.MarqueeAnimationSpeed = 10;
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(535, 2);
this.progressBar1.TabIndex = 3;
//
// wLogViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(695, 450);
this.Controls.Add(this.splitContainer1);
this.Controls.Add(this.toolStrip1);
this.Name = "wLogViewer";
this.Text = "wLogViewer";
this.Load += new System.EventHandler(this.wLogViewer_Load);
this.Shown += new System.EventHandler(this.wLogViewer_Shown);
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripLabel toolStripLabel1;
private System.Windows.Forms.ToolStripTextBox tstbLogPath;
private System.Windows.Forms.ToolStripButton tsbSelectPath;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.ProgressBar progressBar1;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
//
using Tools.MyCommon;
using Tools.MyUtils;
namespace Tools.UI
{
public partial class wLogViewer : wBasic
{
string LogPath { get => this.tstbLogPath.Text; set => this.tstbLogPath.Text = value; }
public wLogViewer()
{
InitializeComponent();
}
//窗体:加载
private void wLogViewer_Load(object sender, EventArgs e)
{
}
//窗体:显示完成
private void wLogViewer_Shown(object sender, EventArgs e)
{
this.tsbSelectPath.Click += TsbSelectPath_Click;
this.tstbLogPath.TextChanged += TstbLogPath_TextChanged;
this.listBox1.SelectedIndexChanged += ListBox1_SelectedIndexChanged;
}
/// <summary>
/// 选择路径
/// </summary>
private void TsbSelectPath_Click(object sender, EventArgs e)
{
var folder = Utils.SelectFolder();
if (!string.IsNullOrEmpty(folder))
{
this.LogPath = folder;
}
}
/// <summary>
/// 路径文本改变时,刷新列表框
/// </summary>
private void TstbLogPath_TextChanged(object sender, EventArgs e)
{
this.InitListBox();
}
Task _task = null;
CancellationTokenSource _tokenSource = new CancellationTokenSource();
/// <summary>
/// 列表切换:加载选中日志文件
/// </summary>
private void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var fileName = this.listBox1.SelectedItem.ToString();
var isDefault = fileName.ToLower().EndsWith(".log");
//清空信息
this.textBox1.Text = string.Empty;
//如果上一个任务还未结束,则取消
if (_task != null && !_task.IsCompleted)
{
_tokenSource.Cancel();
}
//异步读取
CancellationToken token = this._tokenSource.Token;
this._task = Task.Run(() =>
{
if (token.IsCancellationRequested)
return;
//读取日志内容
var buffer = new byte[1024];
var fs = new FileStream($@"{this.LogPath}\{fileName}", FileMode.Open, FileAccess.Read);
//设定
this.AsyncUI(() => {
this.progressBar1.Maximum = Math.Max(1, (int)(fs.Length / 1024));
this.progressBar1.Value = 0;
});
StringBuilder sb = new StringBuilder(1024);
while (fs.Read(buffer, 0, buffer.Length) > 0)
{
this.AsyncUI(() =>
{
if (this.progressBar1.Value < this.progressBar1.Maximum)
this.progressBar1.Value += 1;
});
sb.Append(isDefault ? Encoding.Default.GetString(buffer) : Encoding.UTF8.GetString(buffer));
}
//显示日志内容
this.AsyncUI(() => this.textBox1.Text = sb.ToString());
//释放资源
sb.Clear();
fs.Close();
}, token);
}
/// <summary>
/// 日志文件类型(兼容原有的txt日志和log4net日志)
/// </summary>
List<string> LogExtensions = new List<string> { ".txt", ".log" };
/// <summary>
/// 初始化列表框
/// </summary>
private void InitListBox()
{
//清空原有项
this.textBox1.Text = string.Empty;
this.listBox1.Items.Clear();
//重新加载
if (Directory.Exists(this.LogPath))
{
var dirInfo = new DirectoryInfo(this.LogPath);
var files = dirInfo.GetFiles().Where(f => this.LogExtensions.Contains(f.Extension.ToLower())).Select(f => f.Name);
this.listBox1.Items.AddRange(files.ToArray());
}
else
{
Utils.Tip("路径不存在,请检查!");
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
\ No newline at end of file
...@@ -33,6 +33,7 @@ namespace Tools ...@@ -33,6 +33,7 @@ namespace Tools
this.CreateModule(Tools_imp, typeof(UpdateExecuter.frmMain), "更新执行工具", "xj:用于客户更新和执行SQL脚本"), this.CreateModule(Tools_imp, typeof(UpdateExecuter.frmMain), "更新执行工具", "xj:用于客户更新和执行SQL脚本"),
this.CreateModule(Tools_imp, typeof(UI.wEmptyTable), "清空表", "tr:输入主表、自动清空关联表的工具"), this.CreateModule(Tools_imp, typeof(UI.wEmptyTable), "清空表", "tr:输入主表、自动清空关联表的工具"),
this.CreateModule(Tools_imp, typeof(UI.wExcelExportSetting), "Excel导出设置", "tr:Excel导出配置图形化版本"), this.CreateModule(Tools_imp, typeof(UI.wExcelExportSetting), "Excel导出设置", "tr:Excel导出配置图形化版本"),
this.CreateModule(Tools_imp, typeof(UI.wLogViewer), "日志查看器", "tr:可以方便的查看系统日志"),
//------------------------------- //-------------------------------
this.CreateModule(Tools_dev, typeof(Ftt.PatchPack.FrmMain), "自动打包工具", "xj:用于CS后端程序自动打包成压缩包"), this.CreateModule(Tools_dev, typeof(Ftt.PatchPack.FrmMain), "自动打包工具", "xj:用于CS后端程序自动打包成压缩包"),
this.CreateModule(Tools_dev, typeof(UI.wSysModule), "功能模块管理", "xj:管理功能模块和代码窗体的映射"), this.CreateModule(Tools_dev, typeof(UI.wSysModule), "功能模块管理", "xj:管理功能模块和代码窗体的映射"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment