초기 커밋.
This commit is contained in:
1077
JWH/CONTROL/GridViewEx.cs
Normal file
1077
JWH/CONTROL/GridViewEx.cs
Normal file
File diff suppressed because it is too large
Load Diff
34
JWH/CONTROL/ListViewItemComparer.cs
Normal file
34
JWH/CONTROL/ListViewItemComparer.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace JWH.CONTROL
|
||||
{
|
||||
|
||||
public class ListViewItemComparer : IComparer
|
||||
{
|
||||
|
||||
public int Column { get; set; } = 0;
|
||||
public System.Windows.Forms.SortOrder SortOrder { get; set; } = System.Windows.Forms.SortOrder.Ascending;
|
||||
|
||||
public ListViewItemComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public ListViewItemComparer(int column, System.Windows.Forms.SortOrder order = System.Windows.Forms.SortOrder.Ascending)
|
||||
{
|
||||
this.Column = column;
|
||||
this.SortOrder = order;
|
||||
}
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
int rtnValue = -1;
|
||||
rtnValue = String.Compare(((ListViewItem)x).SubItems[this.Column].Text, ((ListViewItem)y).SubItems[this.Column].Text);
|
||||
if (this.SortOrder == System.Windows.Forms.SortOrder.Descending) rtnValue *= -1;
|
||||
return rtnValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
63
JWH/DATA/CustomerAttributes.cs
Normal file
63
JWH/DATA/CustomerAttributes.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace JWH.DATA
|
||||
{
|
||||
|
||||
public static class CustomerAttributes
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Primary Key Attribute
|
||||
/// </summary>
|
||||
public sealed class PrimaryKeyAttribute : Attribute
|
||||
{
|
||||
|
||||
public bool PrimaryKey { get; }
|
||||
|
||||
public PrimaryKeyAttribute(bool value)
|
||||
{
|
||||
this.PrimaryKey = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Length Attribute
|
||||
/// </summary>
|
||||
public sealed class LengthAttribute : Attribute
|
||||
{
|
||||
|
||||
public int Length { get; }
|
||||
|
||||
public LengthAttribute(int length)
|
||||
{
|
||||
this.Length = length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PropertyInfo.LengthAttribute 속성값을 반환한다
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetPropertyLength(this PropertyInfo property)
|
||||
{
|
||||
try
|
||||
{
|
||||
LengthAttribute attribute = (LengthAttribute)Attribute.GetCustomAttribute(property, typeof(LengthAttribute), true);
|
||||
if (attribute == null) return 0;
|
||||
|
||||
return attribute.Length;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
9
JWH/DATA/DataTableBase.cs
Normal file
9
JWH/DATA/DataTableBase.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace JWH.DATA
|
||||
{
|
||||
|
||||
public class DataTableBase
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
290
JWH/DOCKFORM/DockForm.Designer.cs
generated
Normal file
290
JWH/DOCKFORM/DockForm.Designer.cs
generated
Normal file
@@ -0,0 +1,290 @@
|
||||
namespace JWH.DOCKFORM
|
||||
{
|
||||
partial class DockForm
|
||||
{
|
||||
/// <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.radDock1 = new Telerik.WinControls.UI.Docking.RadDock();
|
||||
this.documentContainer1 = new Telerik.WinControls.UI.Docking.DocumentContainer();
|
||||
this.toolWindow1 = new Telerik.WinControls.UI.Docking.ToolWindow();
|
||||
this.toolWindow2 = new Telerik.WinControls.UI.Docking.ToolWindow();
|
||||
this.toolTabStrip2 = new Telerik.WinControls.UI.Docking.ToolTabStrip();
|
||||
this.toolWindow3 = new Telerik.WinControls.UI.Docking.ToolWindow();
|
||||
this.toolTabStrip3 = new Telerik.WinControls.UI.Docking.ToolTabStrip();
|
||||
this.toolWindow4 = new Telerik.WinControls.UI.Docking.ToolWindow();
|
||||
this.toolTabStrip4 = new Telerik.WinControls.UI.Docking.ToolTabStrip();
|
||||
this.radSplitContainer2 = new Telerik.WinControls.UI.RadSplitContainer();
|
||||
this.toolTabStrip5 = new Telerik.WinControls.UI.Docking.ToolTabStrip();
|
||||
this.documentWindow1 = new Telerik.WinControls.UI.Docking.DocumentWindow();
|
||||
this.documentTabStrip1 = new Telerik.WinControls.UI.Docking.DocumentTabStrip();
|
||||
this.visualStudio2012DarkTheme1 = new Telerik.WinControls.Themes.VisualStudio2012DarkTheme();
|
||||
((System.ComponentModel.ISupportInitialize)(this.radDock1)).BeginInit();
|
||||
this.radDock1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.documentContainer1)).BeginInit();
|
||||
this.documentContainer1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip2)).BeginInit();
|
||||
this.toolTabStrip2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip3)).BeginInit();
|
||||
this.toolTabStrip3.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip4)).BeginInit();
|
||||
this.toolTabStrip4.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.radSplitContainer2)).BeginInit();
|
||||
this.radSplitContainer2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip5)).BeginInit();
|
||||
this.toolTabStrip5.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.documentTabStrip1)).BeginInit();
|
||||
this.documentTabStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// radDock1
|
||||
//
|
||||
this.radDock1.ActiveWindow = this.toolWindow3;
|
||||
this.radDock1.Controls.Add(this.toolTabStrip5);
|
||||
this.radDock1.Controls.Add(this.radSplitContainer2);
|
||||
this.radDock1.Controls.Add(this.toolTabStrip4);
|
||||
this.radDock1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.radDock1.Location = new System.Drawing.Point(3, 3);
|
||||
this.radDock1.MainDocumentContainer = this.documentContainer1;
|
||||
this.radDock1.Name = "radDock1";
|
||||
this.radDock1.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||
//
|
||||
//
|
||||
//
|
||||
this.radDock1.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.radDock1.Size = new System.Drawing.Size(1000, 715);
|
||||
this.radDock1.SplitterWidth = 2;
|
||||
this.radDock1.TabIndex = 0;
|
||||
this.radDock1.TabStop = false;
|
||||
this.radDock1.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// documentContainer1
|
||||
//
|
||||
this.documentContainer1.Controls.Add(this.documentTabStrip1);
|
||||
this.documentContainer1.Name = "documentContainer1";
|
||||
//
|
||||
//
|
||||
//
|
||||
this.documentContainer1.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.documentContainer1.SizeInfo.SizeMode = Telerik.WinControls.UI.Docking.SplitPanelSizeMode.Fill;
|
||||
this.documentContainer1.SplitterWidth = 2;
|
||||
this.documentContainer1.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// toolWindow1
|
||||
//
|
||||
this.toolWindow1.Caption = null;
|
||||
this.toolWindow1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.toolWindow1.Location = new System.Drawing.Point(4, 24);
|
||||
this.toolWindow1.Name = "toolWindow1";
|
||||
this.toolWindow1.PreviousDockState = Telerik.WinControls.UI.Docking.DockState.Docked;
|
||||
this.toolWindow1.Size = new System.Drawing.Size(982, 172);
|
||||
this.toolWindow1.Text = "toolWindow1";
|
||||
//
|
||||
// toolWindow2
|
||||
//
|
||||
this.toolWindow2.Caption = null;
|
||||
this.toolWindow2.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.toolWindow2.Location = new System.Drawing.Point(4, 24);
|
||||
this.toolWindow2.Name = "toolWindow2";
|
||||
this.toolWindow2.PreviousDockState = Telerik.WinControls.UI.Docking.DockState.Docked;
|
||||
this.toolWindow2.Size = new System.Drawing.Size(192, 273);
|
||||
this.toolWindow2.Text = "toolWindow2";
|
||||
//
|
||||
// toolTabStrip2
|
||||
//
|
||||
this.toolTabStrip2.CanUpdateChildIndex = true;
|
||||
this.toolTabStrip2.Controls.Add(this.toolWindow2);
|
||||
this.toolTabStrip2.Location = new System.Drawing.Point(0, 0);
|
||||
this.toolTabStrip2.Name = "toolTabStrip2";
|
||||
//
|
||||
//
|
||||
//
|
||||
this.toolTabStrip2.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.toolTabStrip2.SelectedIndex = 0;
|
||||
this.toolTabStrip2.Size = new System.Drawing.Size(200, 301);
|
||||
this.toolTabStrip2.TabIndex = 1;
|
||||
this.toolTabStrip2.TabStop = false;
|
||||
this.toolTabStrip2.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// toolWindow3
|
||||
//
|
||||
this.toolWindow3.Caption = null;
|
||||
this.toolWindow3.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.toolWindow3.Location = new System.Drawing.Point(4, 24);
|
||||
this.toolWindow3.Name = "toolWindow3";
|
||||
this.toolWindow3.PreviousDockState = Telerik.WinControls.UI.Docking.DockState.Docked;
|
||||
this.toolWindow3.Size = new System.Drawing.Size(192, 273);
|
||||
this.toolWindow3.Text = "toolWindow3";
|
||||
//
|
||||
// toolTabStrip3
|
||||
//
|
||||
this.toolTabStrip3.CanUpdateChildIndex = true;
|
||||
this.toolTabStrip3.Controls.Add(this.toolWindow3);
|
||||
this.toolTabStrip3.Location = new System.Drawing.Point(790, 0);
|
||||
this.toolTabStrip3.Name = "toolTabStrip3";
|
||||
//
|
||||
//
|
||||
//
|
||||
this.toolTabStrip3.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.toolTabStrip3.SelectedIndex = 0;
|
||||
this.toolTabStrip3.Size = new System.Drawing.Size(200, 301);
|
||||
this.toolTabStrip3.TabIndex = 2;
|
||||
this.toolTabStrip3.TabStop = false;
|
||||
this.toolTabStrip3.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// toolWindow4
|
||||
//
|
||||
this.toolWindow4.Caption = null;
|
||||
this.toolWindow4.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.toolWindow4.Location = new System.Drawing.Point(4, 24);
|
||||
this.toolWindow4.Name = "toolWindow4";
|
||||
this.toolWindow4.PreviousDockState = Telerik.WinControls.UI.Docking.DockState.Docked;
|
||||
this.toolWindow4.Size = new System.Drawing.Size(982, 172);
|
||||
this.toolWindow4.Text = "toolWindow4";
|
||||
//
|
||||
// toolTabStrip4
|
||||
//
|
||||
this.toolTabStrip4.CanUpdateChildIndex = true;
|
||||
this.toolTabStrip4.Controls.Add(this.toolWindow4);
|
||||
this.toolTabStrip4.Location = new System.Drawing.Point(5, 510);
|
||||
this.toolTabStrip4.Name = "toolTabStrip4";
|
||||
//
|
||||
//
|
||||
//
|
||||
this.toolTabStrip4.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.toolTabStrip4.SelectedIndex = 0;
|
||||
this.toolTabStrip4.Size = new System.Drawing.Size(990, 200);
|
||||
this.toolTabStrip4.TabIndex = 1;
|
||||
this.toolTabStrip4.TabStop = false;
|
||||
this.toolTabStrip4.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// radSplitContainer2
|
||||
//
|
||||
this.radSplitContainer2.Controls.Add(this.toolTabStrip2);
|
||||
this.radSplitContainer2.Controls.Add(this.documentContainer1);
|
||||
this.radSplitContainer2.Controls.Add(this.toolTabStrip3);
|
||||
this.radSplitContainer2.IsCleanUpTarget = true;
|
||||
this.radSplitContainer2.Location = new System.Drawing.Point(5, 207);
|
||||
this.radSplitContainer2.Name = "radSplitContainer2";
|
||||
this.radSplitContainer2.Padding = new System.Windows.Forms.Padding(5);
|
||||
//
|
||||
//
|
||||
//
|
||||
this.radSplitContainer2.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.radSplitContainer2.Size = new System.Drawing.Size(990, 301);
|
||||
this.radSplitContainer2.SplitterWidth = 2;
|
||||
this.radSplitContainer2.TabIndex = 0;
|
||||
this.radSplitContainer2.TabStop = false;
|
||||
this.radSplitContainer2.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// toolTabStrip5
|
||||
//
|
||||
this.toolTabStrip5.CanUpdateChildIndex = true;
|
||||
this.toolTabStrip5.Controls.Add(this.toolWindow1);
|
||||
this.toolTabStrip5.Location = new System.Drawing.Point(5, 5);
|
||||
this.toolTabStrip5.Name = "toolTabStrip5";
|
||||
//
|
||||
//
|
||||
//
|
||||
this.toolTabStrip5.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.toolTabStrip5.SelectedIndex = 0;
|
||||
this.toolTabStrip5.Size = new System.Drawing.Size(990, 200);
|
||||
this.toolTabStrip5.TabIndex = 2;
|
||||
this.toolTabStrip5.TabStop = false;
|
||||
this.toolTabStrip5.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// documentWindow1
|
||||
//
|
||||
this.documentWindow1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.documentWindow1.Location = new System.Drawing.Point(4, 29);
|
||||
this.documentWindow1.Name = "documentWindow1";
|
||||
this.documentWindow1.PreviousDockState = Telerik.WinControls.UI.Docking.DockState.TabbedDocument;
|
||||
this.documentWindow1.Size = new System.Drawing.Size(578, 268);
|
||||
this.documentWindow1.Text = "documentWindow1";
|
||||
//
|
||||
// documentTabStrip1
|
||||
//
|
||||
this.documentTabStrip1.CanUpdateChildIndex = true;
|
||||
this.documentTabStrip1.Controls.Add(this.documentWindow1);
|
||||
this.documentTabStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.documentTabStrip1.Name = "documentTabStrip1";
|
||||
//
|
||||
//
|
||||
//
|
||||
this.documentTabStrip1.RootElement.MinSize = new System.Drawing.Size(25, 25);
|
||||
this.documentTabStrip1.SelectedIndex = 0;
|
||||
this.documentTabStrip1.Size = new System.Drawing.Size(586, 301);
|
||||
this.documentTabStrip1.TabIndex = 0;
|
||||
this.documentTabStrip1.TabStop = false;
|
||||
this.documentTabStrip1.ThemeName = "VisualStudio2012Dark";
|
||||
//
|
||||
// DockForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1006, 721);
|
||||
this.Controls.Add(this.radDock1);
|
||||
this.Name = "DockForm";
|
||||
this.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.Text = "DockForm";
|
||||
((System.ComponentModel.ISupportInitialize)(this.radDock1)).EndInit();
|
||||
this.radDock1.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.documentContainer1)).EndInit();
|
||||
this.documentContainer1.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip2)).EndInit();
|
||||
this.toolTabStrip2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip3)).EndInit();
|
||||
this.toolTabStrip3.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip4)).EndInit();
|
||||
this.toolTabStrip4.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.radSplitContainer2)).EndInit();
|
||||
this.radSplitContainer2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.toolTabStrip5)).EndInit();
|
||||
this.toolTabStrip5.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.documentTabStrip1)).EndInit();
|
||||
this.documentTabStrip1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Telerik.WinControls.UI.Docking.RadDock radDock1;
|
||||
private Telerik.WinControls.UI.Docking.DocumentContainer documentContainer1;
|
||||
private Telerik.WinControls.UI.Docking.ToolWindow toolWindow3;
|
||||
private Telerik.WinControls.UI.Docking.ToolTabStrip toolTabStrip5;
|
||||
private Telerik.WinControls.UI.Docking.ToolWindow toolWindow1;
|
||||
private Telerik.WinControls.UI.RadSplitContainer radSplitContainer2;
|
||||
private Telerik.WinControls.UI.Docking.ToolTabStrip toolTabStrip2;
|
||||
private Telerik.WinControls.UI.Docking.ToolWindow toolWindow2;
|
||||
private Telerik.WinControls.UI.Docking.DocumentTabStrip documentTabStrip1;
|
||||
private Telerik.WinControls.UI.Docking.DocumentWindow documentWindow1;
|
||||
private Telerik.WinControls.UI.Docking.ToolTabStrip toolTabStrip3;
|
||||
private Telerik.WinControls.UI.Docking.ToolTabStrip toolTabStrip4;
|
||||
private Telerik.WinControls.UI.Docking.ToolWindow toolWindow4;
|
||||
private Telerik.WinControls.Themes.VisualStudio2012DarkTheme visualStudio2012DarkTheme1;
|
||||
}
|
||||
}
|
||||
20
JWH/DOCKFORM/DockForm.cs
Normal file
20
JWH/DOCKFORM/DockForm.cs
Normal file
@@ -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 JWH.DOCKFORM
|
||||
{
|
||||
public partial class DockForm : Form
|
||||
{
|
||||
public DockForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
123
JWH/DOCKFORM/DockForm.resx
Normal file
123
JWH/DOCKFORM/DockForm.resx
Normal file
@@ -0,0 +1,123 @@
|
||||
<?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="visualStudio2012DarkTheme1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
139
JWH/EXTENSIONS/ExtensionAPI.cs
Normal file
139
JWH/EXTENSIONS/ExtensionAPI.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace JWH
|
||||
{
|
||||
|
||||
public static class ExtensionAPI
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 네트워크 리소스
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
public struct NETRESOURCE
|
||||
{
|
||||
public uint dwScope;
|
||||
public uint dwType;
|
||||
public uint dwDisplayType;
|
||||
public uint dwUsage;
|
||||
public string lpLocalName;
|
||||
public string lpRemoteName;
|
||||
public string lpComment;
|
||||
public string lpProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set Tab stops to a width of 4
|
||||
/// </summary>
|
||||
private const int EM_SETTABSTOPS = 0x00CB;
|
||||
|
||||
/// <summary>
|
||||
/// 네트워크 드라이브 연결
|
||||
/// </summary>
|
||||
/// <param name="hwndOwner"></param>
|
||||
/// <param name="lpNetResource"></param>
|
||||
/// <param name="lpPassword"></param>
|
||||
/// <param name="lpUserID"></param>
|
||||
/// <param name="dwFlags"></param>
|
||||
/// <param name="lpAccessName"></param>
|
||||
/// <param name="lpBufferSize"></param>
|
||||
/// <param name="lpResult"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("mpr.dll", CharSet = CharSet.Auto)]
|
||||
public static extern int WNetUseConnection(
|
||||
IntPtr hwndOwner,
|
||||
[MarshalAs(UnmanagedType.Struct)] ref NETRESOURCE lpNetResource,
|
||||
string lpPassword,
|
||||
string lpUserID,
|
||||
uint dwFlags,
|
||||
StringBuilder lpAccessName,
|
||||
ref int lpBufferSize,
|
||||
out uint lpResult);
|
||||
|
||||
/// <summary>
|
||||
/// 네트워크 드라이브 해제
|
||||
/// </summary>
|
||||
/// <param name="lpName"></param>
|
||||
/// <param name="dwFlags"></param>
|
||||
/// <param name="fForce"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("mpr.dll", EntryPoint = "WNetCancelConnection2", CharSet = CharSet.Auto)]
|
||||
public static extern int WNetCancelConnection2A(string lpName, int dwFlags, int fForce);
|
||||
|
||||
/// <summary>
|
||||
/// 네트워크 드라이브 연결
|
||||
/// </summary>
|
||||
/// <param name="server"></param>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="pwd"></param>
|
||||
/// <returns></returns>
|
||||
public static int ConnectRemoteServer(string server, string uid, string pwd)
|
||||
{
|
||||
int capacity = 64;
|
||||
uint resultFlags = 0;
|
||||
uint flags = 0;
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder(capacity);
|
||||
NETRESOURCE ns = new NETRESOURCE();
|
||||
ns.dwType = 1; // 공유 디스크
|
||||
ns.lpLocalName = null; // 로컬 드라이브 지정하지 않음
|
||||
ns.lpRemoteName = $@"\\{server}";
|
||||
ns.lpProvider = null;
|
||||
int result = 0;
|
||||
|
||||
result = WNetUseConnection(IntPtr.Zero, ref ns, pwd, uid, flags, sb, ref capacity, out resultFlags);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 네트워크 드라이브 해제
|
||||
/// </summary>
|
||||
/// <param name="server"></param>
|
||||
/// <returns></returns>
|
||||
public static int CencelRemoteServer(string server)
|
||||
{
|
||||
string lpRemoteName = $@"\\{server}";
|
||||
int result = 0;
|
||||
|
||||
result = WNetCancelConnection2A(lpRemoteName, 1, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SendMessage
|
||||
/// </summary>
|
||||
/// <param name="h"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="wParam"></param>
|
||||
/// <param name="lParam"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam);
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트박스의 탭 간격을 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="tabWidths">탭간격</param>
|
||||
public static void SetTabWidth(this TextBox sender, params int[] tabWidths)
|
||||
{
|
||||
Graphics graphics = sender.CreateGraphics();
|
||||
int characterWidth = 4;
|
||||
//characterWidth = (int)graphics.MeasureString("A", sender.Font).Width;
|
||||
|
||||
int[] lParams = new int[tabWidths.Length];
|
||||
for(int i=0; i< tabWidths.Length; i++)
|
||||
{
|
||||
lParams[i] = tabWidths[i] * characterWidth;
|
||||
if (i > 0) lParams[i] += lParams[i - 1];
|
||||
}
|
||||
|
||||
IntPtr ptr = SendMessage(sender.Handle, EM_SETTABSTOPS, lParams.Length, lParams);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
531
JWH/EXTENSIONS/ExtensionByte.cs
Normal file
531
JWH/EXTENSIONS/ExtensionByte.cs
Normal file
@@ -0,0 +1,531 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
|
||||
namespace JWH
|
||||
{
|
||||
|
||||
public static class ExtensionByte
|
||||
{
|
||||
|
||||
#region [ Byte ] ------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 바이트 배열을 복제합니다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] Clone(this byte[] sender, int offset = -1, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (offset < 0) offset = 0;
|
||||
if (length < 0) length = sender.Length - offset;
|
||||
if (length > sender.Length - offset) length = sender.Length - offset;
|
||||
|
||||
byte[] value = new byte[length];
|
||||
Buffer.BlockCopy(sender, offset, value, 0, length);
|
||||
|
||||
return value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ String ] ----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 문자열을 바이트 배열로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ConvertBytes(this string sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Encoding.Default.GetBytes(sender);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 진수형태의 문자열을 바이트 배열로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="fromBase">문자열 값의 기수로서 2, 8, 10 또는 16이어야 합니다.</param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ConvertBytes(this string sender, int fromBase)
|
||||
{
|
||||
try
|
||||
{
|
||||
char[] arrContains = "0123456789ABCDEF".Substring(0, fromBase).ToCharArray();
|
||||
|
||||
// 기수에서 허용하지 않는 문자를 필터링
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string value = sender.ToUpper();
|
||||
foreach (char ch in value.ToCharArray())
|
||||
{
|
||||
if (arrContains.Contains(ch) == false) continue;
|
||||
sb.Append(ch);
|
||||
}
|
||||
|
||||
value = sb.ToString();
|
||||
List<byte> bytes = new List<byte>();
|
||||
int step = fromBase > 10 ? 2 : 1;
|
||||
if (fromBase == 2) step = 8;
|
||||
for (int i = 0; i < value.Length; i += step)
|
||||
{
|
||||
if (i + step > value.Length) break;
|
||||
byte byteValue = Convert.ToByte(value.Substring(i, step), fromBase);
|
||||
bytes.Add(byteValue);
|
||||
}
|
||||
|
||||
return bytes.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 바이트 배열을 문자열로 변환합니다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static string ConvertString(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sender == null) return string.Empty;
|
||||
if (length < 0) length = sender.Length;
|
||||
|
||||
return Encoding.Default.GetString(sender, index, length);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 바이트 배열을 HEX 문자열로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static string ConvertHexString(this byte[] sender, int lineFeed = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sender == null) return string.Empty;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int index = 0;
|
||||
int length = (lineFeed <= 0 ? int.MaxValue : lineFeed);
|
||||
while (true)
|
||||
{
|
||||
if (index + length > sender.Length) length = sender.Length - index;
|
||||
if (length == 0) break;
|
||||
sb.AppendLine(BitConverter.ToString(sender, index, length).Replace("-", " "));
|
||||
index += length;
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HEX 문자열을 Byte[]로 변환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ToByteFromHexString(this string sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
int mod = sender.Length % 2;
|
||||
if (mod != 0) return null;
|
||||
|
||||
byte[] array = new byte[sender.Length / 2];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
array[i] = Convert.ToByte(sender.Substring(i * 2, 2), 16);
|
||||
|
||||
return array;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Int ] -------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// int 값을 바이트 배열로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="length">Byte Length</param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ConvertByte(this int sender, int length = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] intByte = BitConverter.GetBytes(sender);
|
||||
if (length < 1) length = intByte.Length;
|
||||
|
||||
byte[] convByte = new byte[length];
|
||||
Array.Copy(intByte, convByte, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(convByte);
|
||||
|
||||
return convByte;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 바이트 배열값을 Int로 변환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="startIndex"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static int ConvertInt(this byte[] sender, int startIndex = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sender == null) return 0;
|
||||
if (length == -1) length = sender.Length;
|
||||
|
||||
byte[] byteBuff = new byte[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
byteBuff[i] = sender[startIndex + i];
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
int value = 0;
|
||||
for (int i = 0; i < length; i++)
|
||||
value |= byteBuff[i] << (i * 8);
|
||||
|
||||
return value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return 0;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 2바이트 배열 값을 short(Int16) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static short ConvertInt16(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[2];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToInt16(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 4바이트 배열 값을 int(Int32) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static int ConvertInt32(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[4];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToInt32(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 8바이트 배열 값을 long(Int64) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static long ConvertInt64(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[8];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToInt64(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 2바이트 배열 값을 ushort(UInt16) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static ushort ConvertUInt16(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[2];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToUInt16(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 4바이트 배열 값을 ulong(UInt32) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static ulong ConvertUInt32(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[4];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToUInt32(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 8바이트 배열 값을 ulong(UInt64) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static ulong ConvertUInt64(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[8];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToUInt64(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 4바이트 배열 값을 float(Single 단정밀도 부동 소수점) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static float ConvertSingle(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[4];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToSingle(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 8바이트 배열 값을 double(배정밀도 부동 소수점) 값으로 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
public static double ConvertDouble(this byte[] sender, int index = 0, int length = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
int destIndex = 0;
|
||||
byte[] byteBuff = new byte[8];
|
||||
|
||||
if (sender == null) return 0;
|
||||
if (length < 1) length = sender.Length;
|
||||
if (length > byteBuff.Length) length = byteBuff.Length;
|
||||
destIndex = byteBuff.Length - length;
|
||||
|
||||
Array.Copy(sender, index, byteBuff, destIndex, length);
|
||||
if (BitConverter.IsLittleEndian) Array.Reverse(byteBuff);
|
||||
|
||||
return BitConverter.ToDouble(byteBuff, 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// ToObject
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="array"></param>
|
||||
/// <returns></returns>
|
||||
public static T ToObject<T>(this byte[] array) where T : class, new()
|
||||
{
|
||||
try
|
||||
{
|
||||
T obj = new T();
|
||||
using (MemoryStream stream = new MemoryStream(array))
|
||||
{
|
||||
BinaryFormatter formatter = new BinaryFormatter();
|
||||
stream.Position = 0;
|
||||
obj = (T)formatter.Deserialize(stream);
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
33
JWH/EXTENSIONS/ExtensionNetwork.cs
Normal file
33
JWH/EXTENSIONS/ExtensionNetwork.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JWH
|
||||
{
|
||||
|
||||
public static class ExtensionNetwork
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Get PhysicalAddress (MAC Address)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetPhysicalAddress()
|
||||
{
|
||||
|
||||
List<NetworkInterface> list = new List<NetworkInterface>();
|
||||
foreach(NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
if (nic.OperationalStatus == OperationalStatus.Up)
|
||||
list.Add(nic);
|
||||
}
|
||||
|
||||
return list[0].GetPhysicalAddress().ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
505
JWH/EXTENSIONS/ExtensionReflection.cs
Normal file
505
JWH/EXTENSIONS/ExtensionReflection.cs
Normal file
@@ -0,0 +1,505 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace JWH
|
||||
{
|
||||
|
||||
public static class ExtensionReflection
|
||||
{
|
||||
|
||||
public static bool IsDesignMode = LicenseManager.UsageMode == LicenseUsageMode.Designtime;
|
||||
|
||||
|
||||
#region [ PropertiesCopy ] --------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 현재객체의 속성값을 대상객체의 속성에 복사합니다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="dest">대상객체</param>
|
||||
public static void PropertiesCopy(this object sender, object dest, bool overwrite = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (PropertyInfo property in sender.GetType().GetProperties())
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyInfo destProp = dest.GetType().GetProperty(property.Name, property.PropertyType);
|
||||
if (destProp == null || property.GetType() != destProp.GetType()) continue;
|
||||
//if (!property.CanWrite) continue;
|
||||
if (!destProp.CanWrite) continue;
|
||||
|
||||
var destValue = destProp.GetValue(dest);
|
||||
if (overwrite == false && destValue != null) continue;
|
||||
|
||||
destProp.SetValue(dest, property.GetValue(sender));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재객체의 속성값을 대상객체의 속성에 복사합니다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="dest">대상객체</param>
|
||||
public static void PropertiesCopy(this DataTable sender, object dest)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sender.Rows.Count < 1) return;
|
||||
|
||||
DataRow row = sender.Rows[0];
|
||||
foreach (DataColumn column in sender.Columns)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyInfo destProp = dest.GetType().GetProperty(column.ColumnName, column.DataType);
|
||||
if (destProp == null) continue;
|
||||
|
||||
try
|
||||
{
|
||||
var obj = row[column.ColumnName];
|
||||
destProp.SetValue(dest, obj);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Object of type 'System.DBNull' cannot be converted to type 'System.String'.
|
||||
// XLogger.Instance.Warn(ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary<string, object>의 값을 대상객체의 속성에 복사합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="dest"></param>
|
||||
public static void PropertiesCopy(this Dictionary<string, object> sender, object dest)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (KeyValuePair<string, object> item in sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyInfo destProp = dest.GetType().GetProperty(item.Key);
|
||||
if (destProp == null) continue;
|
||||
if (!destProp.CanWrite) continue;
|
||||
|
||||
var obj = Convert.ChangeType(item.Value, destProp.PropertyType);
|
||||
destProp.SetValue(dest, obj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// value 값을 현재객체의 속성에 복사합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void PropertySet(this object sender, string name, object value)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyInfo property = sender.GetType().GetProperty(name);
|
||||
if (property == null)
|
||||
foreach (PropertyInfo item in sender.GetType().GetProperties())
|
||||
if (string.Compare(item.Name, name, true) == 0)
|
||||
{
|
||||
property = item;
|
||||
break;
|
||||
}
|
||||
if (property == null) return;
|
||||
if (property.PropertyType != value.GetType())
|
||||
{
|
||||
try
|
||||
{ value = Convert.ChangeType(value, property.PropertyType); }
|
||||
catch
|
||||
{ return; }
|
||||
}
|
||||
|
||||
property.SetValue(sender, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 객체의 속성값을 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static string PropertyGet(this object sender, string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyInfo property = sender.GetType().GetProperty(name);
|
||||
if (property == null)
|
||||
{
|
||||
foreach (PropertyInfo item in sender.GetType().GetProperties())
|
||||
{
|
||||
if (string.Compare(item.Name, name, true) == 0)
|
||||
{
|
||||
property = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (property == null) return string.Empty;
|
||||
return property.GetValue(sender)?.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 객체의 메소드를 호출합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
public static object CallMethod(this object sender, string name, object[] parameters)
|
||||
{
|
||||
MethodInfo method = sender.GetType().GetMethod(name);
|
||||
if (method == null) return false;
|
||||
|
||||
return method.Invoke(sender, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 객체의 속성 정보를 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetPropertiesString(this object sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine($"Type is {sender.GetType()}");
|
||||
foreach (PropertyInfo property in sender.GetType().GetProperties())
|
||||
{
|
||||
try
|
||||
{
|
||||
sb.AppendLine($" > {property.Name} = {property.GetValue(sender)}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 객체를 복제합니다.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static T Clone<T>(this T sender) where T : class, new()
|
||||
{
|
||||
T obj = new T();
|
||||
try
|
||||
{
|
||||
sender.PropertiesCopy(obj);
|
||||
return obj;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#region [ GetStringValue(Enum) ] --------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Will get the string value for a given enums value, this will
|
||||
/// only work if you assign the StringValue attribute to
|
||||
/// the items in your enum.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetStringValue(this Enum value)
|
||||
{
|
||||
// Get the type
|
||||
Type type = value.GetType();
|
||||
|
||||
// Get fieldinfo for this type
|
||||
FieldInfo fieldInfo = type.GetField(value.ToString());
|
||||
|
||||
// Get the stringvalue attributes
|
||||
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
|
||||
typeof(StringValueAttribute), false) as StringValueAttribute[];
|
||||
|
||||
// Return the first if there was a match.
|
||||
return attribs.Length > 0 ? attribs[0].StringValue : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This attribute is used to represent a string value
|
||||
/// for a value in an enum.
|
||||
/// </summary>
|
||||
public class StringValueAttribute : Attribute
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Holds the stringvalue for a value in an enum.
|
||||
/// </summary>
|
||||
public string StringValue { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to init a StringValue Attribute
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public StringValueAttribute(string value)
|
||||
{
|
||||
this.StringValue = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// GetDescription
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetDescription<T>(this T e) where T : IConvertible
|
||||
{
|
||||
if (e is Enum)
|
||||
{
|
||||
Type type = e.GetType();
|
||||
Array values = Enum.GetValues(type);
|
||||
|
||||
foreach (int val in values)
|
||||
{
|
||||
if (val == e.ToInt32(CultureInfo.InvariantCulture))
|
||||
{
|
||||
var memInfo = type.GetMember(type.GetEnumName(val));
|
||||
var descriptionAttribute = memInfo[0]
|
||||
.GetCustomAttributes(typeof(DescriptionAttribute), false)
|
||||
.FirstOrDefault() as DescriptionAttribute;
|
||||
|
||||
if (descriptionAttribute != null)
|
||||
{
|
||||
return descriptionAttribute.Description;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#region [ ToClass() ] -------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Converts a DataTable to a list with generic objects
|
||||
/// dataTable.ToClass<Employee>();
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Generic object</typeparam>
|
||||
/// <param name="dataTable">DataTable</param>
|
||||
/// <returns>List with generic objects</returns>
|
||||
public static T[] ToClass<T>(this DataTable dataTable) where T : class, new()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
foreach (var row in dataTable.AsEnumerable())
|
||||
{
|
||||
T obj = new T();
|
||||
|
||||
foreach (PropertyInfo property in obj.GetType().GetProperties())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (dataTable.Columns.Contains(property.Name) == false) continue;
|
||||
if (row[property.Name] is System.DBNull) continue;
|
||||
|
||||
var val = row[property.Name];
|
||||
//if (property.PropertyType == typeof(DateTime) && val.GetType() == typeof(string))
|
||||
// DateTime.TryParse(val.ToString(), out val);
|
||||
|
||||
property.SetValue(obj, Convert.ChangeType(val, property.PropertyType, CultureInfo.CurrentCulture), null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
list.Add(obj);
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
catch { throw; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a object to a list with generic objects
|
||||
/// dataTable.ToClass<Employee>();
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Generic object</typeparam>
|
||||
/// <param name="srcArray">DataTable</param>
|
||||
/// <returns>List with generic objects</returns>
|
||||
public static T[] ToClass<T>(this object[] srcArray) where T : class, new()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
|
||||
foreach (object src in srcArray)
|
||||
{
|
||||
T des = new T();
|
||||
list.Add(des);
|
||||
Type desType = des.GetType();
|
||||
|
||||
Type srcType = src.GetType();
|
||||
foreach (PropertyInfo srcProperty in srcType.GetProperties())
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyInfo desProperty = desType.GetProperty(srcProperty.Name);
|
||||
if (desProperty == null) continue;
|
||||
|
||||
var srcValue = srcProperty.GetValue(src);
|
||||
if (srcProperty.PropertyType != desProperty.PropertyType)
|
||||
{
|
||||
srcValue = Convert.ChangeType(srcValue, desProperty.PropertyType);
|
||||
}
|
||||
|
||||
desProperty.SetValue(des, srcValue);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Warn(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return list.ToArray();
|
||||
}
|
||||
catch { throw; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static CultureInfo CultureInfo { get; set; }
|
||||
|
||||
public static string ToTitleCase(this string sender)
|
||||
{
|
||||
if (ExtensionReflection.CultureInfo == null)
|
||||
ExtensionReflection.CultureInfo = CultureInfo.CurrentCulture;
|
||||
|
||||
TextInfo textInfo = CultureInfo.TextInfo;
|
||||
|
||||
return textInfo.ToTitleCase(sender.ToLower());
|
||||
}
|
||||
|
||||
public static Bitmap ControlCapture(this Control control, bool clipboard = true)
|
||||
{
|
||||
if (control == null) throw new ArgumentNullException("control");
|
||||
|
||||
Bitmap bitmap = new Bitmap(control.Width, control.Height);
|
||||
control.DrawToBitmap(bitmap, new Rectangle(new Point(0, 0), control.Size));
|
||||
if (clipboard) Clipboard.SetImage(bitmap);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap ControlCapture(this Control control, Rectangle rect, bool clipboard = true)
|
||||
{
|
||||
if (control == null) throw new ArgumentNullException("control");
|
||||
|
||||
Bitmap bitmap = new Bitmap(rect.Width, rect.Height);
|
||||
control.DrawToBitmap(bitmap, rect);
|
||||
if (clipboard) Clipboard.SetImage(bitmap);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 문자열을 열거형으로 반환한다
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static T ToEnum<T>(this string sender, T value)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (T)Enum.Parse(typeof(T), sender, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
603
JWH/EXTENSIONS/ExtensionXml.cs
Normal file
603
JWH/EXTENSIONS/ExtensionXml.cs
Normal file
@@ -0,0 +1,603 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace JWH
|
||||
{
|
||||
|
||||
public static class ExtensionXml
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 이름으로 노드를 검색하여 첫번째 노드를 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="fullScan">하위검색</param>
|
||||
/// <returns></returns>
|
||||
public static XmlNode GetSingleNodeByName(this XmlDocument sender, string name, bool fullScan = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (string.Compare(node.Name, name, true) == 0) return node;
|
||||
}
|
||||
if (fullScan == false) return null;
|
||||
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
XmlNode result = node.GetSingleNodeByName(name);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 이름으로 노드를 검색하여 첫번째 노드를 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="fullScan">하위검색</param>
|
||||
/// <returns></returns>
|
||||
public static XmlNode GetSingleNodeByName(this XmlNode sender, string name, bool fullScan = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (string.Compare(node.Name, name, true) == 0) return node;
|
||||
}
|
||||
if (fullScan == false) return null;
|
||||
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
XmlNode result = node.GetSingleNodeByName(name);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 이름으로 노드를 검색하여 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="fullScan">하위검색</param>
|
||||
/// <returns></returns>
|
||||
public static XmlNode[] GetNodesByName(this XmlDocument sender, string name, bool fullScan = true)
|
||||
{
|
||||
List<XmlNode> nodes = new List<XmlNode>();
|
||||
try
|
||||
{
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (string.Compare(node.Name, name, true) == 0)
|
||||
nodes.Add(node);
|
||||
}
|
||||
if (fullScan == false) return nodes.ToArray();
|
||||
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
nodes.AddRange(node.GetNodesByName(name));
|
||||
}
|
||||
|
||||
return nodes.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 이름으로 노드를 검색하여 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="fullScan">하위검색</param>
|
||||
/// <returns></returns>
|
||||
public static XmlNode[] GetNodesByName(this XmlNode sender, string name, bool fullScan = true)
|
||||
{
|
||||
List<XmlNode> nodes = new List<XmlNode>();
|
||||
try
|
||||
{
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (string.Compare(node.Name, name, true) == 0)
|
||||
nodes.Add(node);
|
||||
}
|
||||
if (fullScan == false) return nodes.ToArray();
|
||||
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
nodes.AddRange(node.GetNodesByName(name));
|
||||
}
|
||||
|
||||
return nodes.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 경로를 검색하여 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static XmlNode[] GetNodesByPath(this XmlDocument sender, string path)
|
||||
{
|
||||
List<XmlNode> nodes = new List<XmlNode>();
|
||||
List<XmlNode> childs = new List<XmlNode>();
|
||||
try
|
||||
{
|
||||
string[] names = path.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (string.Compare(node.Name, names[0], true) == 0)
|
||||
{
|
||||
if (names.Length > 1) childs.Add(node);
|
||||
else nodes.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i < names.Length; i++)
|
||||
sb.AppendFormat($"/{names[i]}");
|
||||
|
||||
foreach (XmlNode node in childs)
|
||||
{
|
||||
nodes.AddRange(node.GetNodesByPath(sb.ToString()));
|
||||
}
|
||||
|
||||
return nodes.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 경로를 검색하여 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static XmlNode[] GetNodesByPath(this XmlNode sender, string path)
|
||||
{
|
||||
List<XmlNode> nodes = new List<XmlNode>();
|
||||
List<XmlNode> childs = new List<XmlNode>();
|
||||
try
|
||||
{
|
||||
string[] names = path.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (string.Compare(node.Name, names[0], true) == 0)
|
||||
{
|
||||
if (names.Length > 1) childs.Add(node);
|
||||
else nodes.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i < names.Length; i++)
|
||||
sb.AppendFormat($"/{names[i]}");
|
||||
|
||||
foreach (XmlNode node in childs)
|
||||
{
|
||||
nodes.AddRange(node.GetNodesByPath(sb.ToString()));
|
||||
}
|
||||
|
||||
return nodes.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 속성이 동일한 노드를 검색하여 반환한다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="ignorsCaseName">Name의 대/소문자 무시</param>
|
||||
/// <param name="ignorsCaseValue">Value의 대/소문자 무시</param>
|
||||
/// <param name="attributes"></param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckAttributes(this XmlNode sender, bool ignorsCaseName = true, bool ignorsCaseValue = false, params KeyValuePair<string, string>[] attributes)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (KeyValuePair<string, string> pair in attributes)
|
||||
{
|
||||
foreach (XmlAttribute attribute in sender.Attributes)
|
||||
{
|
||||
if (string.Compare(pair.Key, attribute.Name, ignorsCaseName) == 0)
|
||||
if (string.Compare(pair.Value, attribute.Value, ignorsCaseValue) == 0) continue;
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 노드의 속성을 검색한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="ignorsCaseName">Attribute.Name 대/소문자 무시</param>
|
||||
/// <returns></returns>
|
||||
public static XmlAttribute GetAttribute(this XmlNode sender, string name, bool ignorsCase = true)
|
||||
{
|
||||
if (sender == null || sender.Attributes == null) return null;
|
||||
|
||||
foreach (XmlAttribute attribute in sender.Attributes)
|
||||
{
|
||||
if (string.Compare(attribute.Name, name, ignorsCase) == 0)
|
||||
return attribute;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 노드의 속성값을 반환한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="ignorsCaseName">Attribute.Name 대/소문자 무시</param>
|
||||
/// <returns></returns>
|
||||
public static string GetAttributeValue(this XmlNode sender, string name, bool ignorsCase = true)
|
||||
{
|
||||
if (sender == null) return null;
|
||||
foreach (XmlAttribute attribute in sender.Attributes)
|
||||
{
|
||||
if (string.Compare(attribute.Name, name, ignorsCase) == 0)
|
||||
return attribute.Value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 노드의 속성값을 변경한다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="ignorsCaseName">Attribute.Name 대/소문자 무시</param>
|
||||
/// <returns></returns>
|
||||
public static string SetAttributeValue(this XmlNode sender, string name, string value, bool ignorsCase = true)
|
||||
{
|
||||
foreach (XmlAttribute attribute in sender.Attributes)
|
||||
{
|
||||
if (string.Compare(attribute.Name, name, ignorsCase) == 0)
|
||||
{
|
||||
attribute.Value = value;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void PropertiesCopyAttribute(this XmlNode sender, object dest)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (XmlAttribute attribute in sender.Attributes)
|
||||
dest.PropertySet(attribute.Name, attribute.Value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void PropertiesCopy(this XmlNode sender, object dest)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
dest.PropertySet(node.Name, node.InnerText);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetText(this XmlNode sender)
|
||||
{
|
||||
if (sender.ChildNodes.Count <= 0) return string.Empty;
|
||||
|
||||
string rtnValue = null;
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (node.GetType() == typeof(XmlText))
|
||||
rtnValue = node.InnerText;
|
||||
}
|
||||
|
||||
return rtnValue;
|
||||
}
|
||||
|
||||
public static void SetText(this XmlNode sender, string value)
|
||||
{
|
||||
XmlNode nodeText = null;
|
||||
foreach (XmlNode node in sender.ChildNodes)
|
||||
{
|
||||
if (node.GetType() == typeof(XmlText))
|
||||
{
|
||||
nodeText.InnerText = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sender.ChildNodes.Count == 0)
|
||||
{
|
||||
sender.InnerText = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// XmlDocument 내용을 문자열로 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="indent"></param>
|
||||
/// <param name="haeder"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetBeautify(this XmlDocument sender, int indent = 2, bool haeder = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
string rtn = string.Empty;
|
||||
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings
|
||||
{
|
||||
Encoding = new UTF8Encoding(false),
|
||||
Indent = true,
|
||||
IndentChars = "".PadLeft(indent),
|
||||
NewLineChars = Environment.NewLine,
|
||||
NewLineHandling = NewLineHandling.Replace,
|
||||
};
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(stream, settings))
|
||||
sender.Save(writer);
|
||||
|
||||
rtn = Encoding.UTF8.GetString(stream.ToArray());
|
||||
}
|
||||
|
||||
if (haeder == false)
|
||||
{
|
||||
int index = rtn.IndexOf("<?");
|
||||
if (index >= 0)
|
||||
{
|
||||
index = rtn.IndexOf("<", index + 1);
|
||||
rtn = rtn.Substring(index);
|
||||
}
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 노드를 XmlDocument에 복사합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="document"></param>
|
||||
/// <param name="isChild"></param>
|
||||
public static void CopyValue(this XmlNode sender, XmlDocument document, bool isChild = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = sender.GetFullPath();
|
||||
foreach (XmlNode child in sender.ChildNodes)
|
||||
{
|
||||
if (child.NodeType == XmlNodeType.Text)
|
||||
{
|
||||
XmlNode dest = document.SelectSingleNode(path);
|
||||
if (dest == null) continue;
|
||||
|
||||
if (dest.ChildNodes.Count == 0)
|
||||
{
|
||||
XmlNode valueNode = document.CreateNode("text", "", "");
|
||||
dest.AppendChild(valueNode);
|
||||
}
|
||||
foreach (XmlNode destChild in dest.ChildNodes)
|
||||
if (destChild.NodeType == XmlNodeType.Text) destChild.Value = child.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isChild) child.CopyValue(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 하위 노드를 생성하고 반환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="innerText"></param>
|
||||
/// <returns></returns>
|
||||
public static XmlNode CreateChildNode(this XmlNode sender, string name, string innerText = "", int index = -1, bool isAfter = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlDocument document = sender.OwnerDocument;
|
||||
XmlNode childNode = document.CreateElement(name);
|
||||
if (!string.IsNullOrEmpty(innerText)) childNode.InnerText = innerText;
|
||||
|
||||
if (index < 0 || index > sender.ChildNodes.Count)
|
||||
{
|
||||
sender.AppendChild(childNode);
|
||||
return childNode;
|
||||
}
|
||||
|
||||
XmlNode refNode = sender.ChildNodes[index];
|
||||
if (isAfter) sender.InsertAfter(childNode, refNode);
|
||||
else sender.InsertBefore(childNode, refNode);
|
||||
|
||||
return childNode;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 노드를 삭제합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public static bool RemoveChildNode(this XmlNode sender, int index)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (index >= sender.ChildNodes.Count) return false;
|
||||
XmlNode node = sender.ChildNodes[index];
|
||||
if (node != null) sender.RemoveChild(node);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 노드를 삭제합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static bool RemoveChildNode(this XmlNode sender, string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlNode node = sender.GetSingleNodeByName(name);
|
||||
if (node == null) return false;
|
||||
sender.RemoveChild(node);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 노드를 삭제합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static bool RemoveChildNodes(this XmlNode sender, string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (XmlNode node in sender.GetNodesByName(name))
|
||||
sender.RemoveChild(node);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetFullPath(this XmlNode sender)
|
||||
{
|
||||
if (sender == null) return string.Empty;
|
||||
if (sender.ParentNode == null || sender.ParentNode.NodeType != XmlNodeType.Element)
|
||||
return $"//{sender.Name}";
|
||||
|
||||
return $"{sender.ParentNode.GetFullPath()}/{sender.Name}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 문자열에 있는 잘못된 XML 문자를 해당하는 올바른 XML로 바꿉니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns>잘못된 문자가 있었으나 바뀐 입력 문자열입니다.</returns>
|
||||
public static string XMLEscape(this string sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
return System.Security.SecurityElement.Escape(sender);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 입력 문자열에서 이스케이프된 문자를 변환합니다.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <returns></returns>
|
||||
public static string XMLUnescape(this string sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
return System.Text.RegularExpressions.Regex.Unescape(sender);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
887
JWH/EXTENSIONS/XLogger.cs
Normal file
887
JWH/EXTENSIONS/XLogger.cs
Normal file
@@ -0,0 +1,887 @@
|
||||
using log4net;
|
||||
using log4net.Appender;
|
||||
using log4net.Config;
|
||||
using log4net.Repository.Hierarchy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using static log4net.Appender.RollingFileAppender;
|
||||
|
||||
namespace JWH
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// log4net을 활용한 로그작성 라이브러리
|
||||
/// [assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
|
||||
/// </summary>
|
||||
public class XLogger
|
||||
{
|
||||
|
||||
#region [ Static ] ====================================================
|
||||
|
||||
/// <summary>
|
||||
/// Logger root
|
||||
/// </summary>
|
||||
public static XLogger Instance { get; set; } = new XLogger();
|
||||
|
||||
/// <summary>
|
||||
/// RollingFileAppender를 생성한다
|
||||
/// </summary>
|
||||
/// <param name="name">Appender.Name</param>
|
||||
/// <param name="file">Appender.File</param>
|
||||
/// <param name="pattern">Appender.ConversionPattern</param>
|
||||
/// <returns></returns>
|
||||
public static RollingFileAppender CreateRollingFileAppender(string name, string path, string pattern)
|
||||
{
|
||||
log4net.Appender.RollingFileAppender appender = new log4net.Appender.RollingFileAppender();
|
||||
try
|
||||
{
|
||||
appender.Name = name;
|
||||
appender.File = $"{path}{name}_";
|
||||
appender.DatePattern = $"yyyyMMddHH'.log'";
|
||||
//appender.MaxSizeRollBackups = 100;
|
||||
appender.MaximumFileSize = "10MB";
|
||||
appender.StaticLogFileName = false;
|
||||
appender.AppendToFile = true;
|
||||
appender.PreserveLogFileNameExtension = true;
|
||||
appender.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Date;
|
||||
appender.LockingModel = new RollingFileAppender.MinimalLock();
|
||||
//appender.CountDirection = XLogger.GetCountDirection(path, $"{name}_", appender.DatePattern);
|
||||
log4net.Layout.PatternLayout layout = new log4net.Layout.PatternLayout() { ConversionPattern = pattern };
|
||||
layout.ActivateOptions();
|
||||
appender.Layout = layout;
|
||||
appender.ActivateOptions();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
|
||||
return appender;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// log4net.GlobalContext.Properties
|
||||
/// <para>You must call ConfigureAndWatch</para>
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void AddProperties(string name, string value)
|
||||
{
|
||||
log4net.GlobalContext.Properties[name] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// log4net.GlobalContext.Properties
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetProperties(string name)
|
||||
{
|
||||
return log4net.GlobalContext.Properties[name] as string;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XmlConfigurator.ConfigureAndWatch
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
public static void ConfigureAndWatch(FileInfo file)
|
||||
{
|
||||
if (file?.Exists == false) return;
|
||||
|
||||
XmlConfigurator.ConfigureAndWatch(file);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Enum ] ======================================================
|
||||
|
||||
/// <summary>XLogLevel</summary>
|
||||
public enum eXLogLevel
|
||||
{
|
||||
None = 0,
|
||||
Debug = 1,
|
||||
Info = 2,
|
||||
Warn = 3,
|
||||
Error = 4,
|
||||
Fatal = 5
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Variable ] ==================================================
|
||||
|
||||
/// <summary>Filter Types</summary>
|
||||
private List<Type> m_FilterTypes = new List<Type>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
/// <summary>Logger Name</summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>log4net.Repository.Hierarchy.Logger</summary>
|
||||
public Logger Logger { get { return this.GetLogger(); } }
|
||||
|
||||
/// <summary>LOG Control</summary>
|
||||
public TextBoxBase Control { get; set; } = null;
|
||||
|
||||
/// <summary>Control.ScrollToCaret</summary>
|
||||
public bool OnScrollToCaret { get; set; } = true;
|
||||
|
||||
/// <summary>LOG Control : 0.DateTime, 1.LogLevel, 2.LogName, 3.ClassFullName, 4.Method, 5.Message, 6.ClassName</summary>
|
||||
/// <example></example>
|
||||
public string ControlPatternLayout { get; set; } = "[{0}] {1} {2} {3}.{4}() {5}";
|
||||
|
||||
/// <summary>Last Deleted LogFile</summary>
|
||||
public DateTime LastDeletedDateTime { get; set; } = DateTime.MinValue;
|
||||
|
||||
/// <summary>Filter Types</summary>
|
||||
public List<Type> FilterTypes
|
||||
{
|
||||
get { return m_FilterTypes; }
|
||||
}
|
||||
|
||||
/// <summary>RichTextBox.SelectionColor</summary>
|
||||
public Color ForeColor { get; set; } = SystemColors.ControlText;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ XLogger ] ===================================================
|
||||
|
||||
/// <summary>
|
||||
/// XLogger
|
||||
/// </summary>
|
||||
public XLogger()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XLogger
|
||||
/// </summary>
|
||||
/// <param name="name">Logger Name defined in log4net.config</param>
|
||||
public XLogger(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ====================================================
|
||||
|
||||
#region [ Appender ] --------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 동적으로 RollingFileAppender를 추가한다
|
||||
/// </summary>
|
||||
public IAppender AddRollingFileAppender(string path, string pattern)
|
||||
{
|
||||
FileAppender appender = null;
|
||||
try
|
||||
{
|
||||
string name = this.Name;
|
||||
appender = XLogger.CreateRollingFileAppender(name, path, pattern);
|
||||
this.AddAppender(appender);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
|
||||
return appender;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 동적으로 RollingFileAppender를 추가한다
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="pattern"></param>
|
||||
public void AddRollingFileAppender(string name, string file, string pattern)
|
||||
{
|
||||
try
|
||||
{
|
||||
log4net.Repository.Hierarchy.Logger logger = this.Logger;
|
||||
RollingFileAppender appender = XLogger.CreateRollingFileAppender(name, file, pattern);
|
||||
this.AddAppender(appender);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 다른 XLogger의 Appender를 추가한다
|
||||
/// </summary>
|
||||
/// <param name="srcXLogger"></param>
|
||||
/// <param name="index"></param>
|
||||
public void AddRollingFileAppender(XLogger srcXLogger, int index = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
log4net.Repository.Hierarchy.Logger srclogger = srcXLogger.Logger;
|
||||
if (srclogger.Appenders.Count <= index) return;
|
||||
|
||||
IAppender srcAppender = srclogger.Appenders[index];
|
||||
this.AddAppender(srcAppender);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appender를 추가한다
|
||||
/// </summary>
|
||||
/// <param name="appender"></param>
|
||||
public void AddAppender(IAppender appender)
|
||||
{
|
||||
try
|
||||
{
|
||||
log4net.Repository.Hierarchy.Logger logger = this.Logger;
|
||||
FileAppender fileAppender = null;
|
||||
IAppender removeItem = null;
|
||||
foreach (IAppender item in logger.Appenders)
|
||||
{
|
||||
if (item.Name == appender.Name)
|
||||
{
|
||||
removeItem = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (removeItem != null)
|
||||
{
|
||||
fileAppender = removeItem as FileAppender;
|
||||
logger.RemoveAppender(removeItem).Close();
|
||||
}
|
||||
|
||||
fileAppender = appender as FileAppender;
|
||||
logger.AddAppender(appender);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모든 Appender를 제거한다
|
||||
/// </summary>
|
||||
public void ClearAppender()
|
||||
{
|
||||
log4net.Repository.Hierarchy.Logger logger = this.Logger;
|
||||
List<IAppender> lstAppender = new List<IAppender>();
|
||||
|
||||
foreach (IAppender item in logger.Appenders)
|
||||
lstAppender.Add(item);
|
||||
|
||||
foreach (IAppender item in lstAppender)
|
||||
logger.RemoveAppender(item).Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ MDC ] -------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// MDC Key
|
||||
/// </summary>
|
||||
private enum eMDCKey
|
||||
{
|
||||
Logger,
|
||||
Name,
|
||||
Class,
|
||||
Method
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set MDC
|
||||
/// </summary>
|
||||
/// <param name="mdcKey"></param>
|
||||
/// <param name="value"></param>
|
||||
private void SetMDC(eMDCKey mdcKey, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
MDC.Set(mdcKey.ToString().ToLower(), value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set MDC
|
||||
/// </summary>
|
||||
/// <param name="mdcKey"></param>
|
||||
/// <param name="value"></param>
|
||||
private void SetMDC(string mdcKey, string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
MDC.Set(mdcKey.ToLower(), value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear MDC
|
||||
/// </summary>
|
||||
private void ClearMDC()
|
||||
{
|
||||
foreach (string mdcKey in Enum.GetNames(typeof(eMDCKey)))
|
||||
SetMDC(mdcKey, string.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Filter ] ----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Add Filter(Type)
|
||||
/// </summary>
|
||||
/// <param name="types"></param>
|
||||
public void AddFilterType(params Type[] types)
|
||||
{
|
||||
m_FilterTypes.AddRange(types);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear Filter(Type)
|
||||
/// </summary>
|
||||
public void ClearFilterType()
|
||||
{
|
||||
m_FilterTypes.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Debug ] -----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Debug
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Debug(object value = null, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Debug, value, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debug
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Debug(string message, Exception e, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Debug, message, e, color);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Info ] ------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Info
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Info(object value = null, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Info, value, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Info(string message, Exception e, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Info, message, e, color);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Warn ] ------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Warn
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Warn(object value = null, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Warn, value, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Warn
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Warn(string message, Exception e, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Warn, message, e, color);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Error ] -----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Error
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Error(object value = null, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Error, value, color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Error
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Error(string message, Exception e, Color? color = null)
|
||||
{
|
||||
return this.WriteLine(eXLogLevel.Error, message, e, color);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Fatal ] -----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Fatal
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public string Fatal(object value, bool showMessageBox)
|
||||
{
|
||||
string message = this.WriteLine(eXLogLevel.Fatal, value);
|
||||
|
||||
if (showMessageBox)
|
||||
MessageBox.Show(message, "Fatal", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fatal
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Fatal(object value = null, Color? color = null)
|
||||
{
|
||||
string result = this.WriteLine(eXLogLevel.Fatal, value, color);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fatal
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="color"></param>
|
||||
public string Fatal(string message, Exception e, Color? color = null)
|
||||
{
|
||||
string result = this.WriteLine(eXLogLevel.Fatal, message, e, color);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fatal
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="showMessageBox">Show MessageBox</param>
|
||||
/// <param name="color"></param>
|
||||
private string xFatal(object value = null, bool showMessageBox = false, Color? color = null)
|
||||
{
|
||||
string result = this.WriteLine(eXLogLevel.Fatal, value, color);
|
||||
if (showMessageBox)
|
||||
MessageBox.Show(result, "Fatal", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fatal
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <param name="showMessageBox">Show MessageBox</param>
|
||||
/// <param name="color"></param>
|
||||
private string xFatal(string message, Exception e, bool showMessageBox = false, Color? color = null)
|
||||
{
|
||||
string result = this.WriteLine(eXLogLevel.Fatal, message, e, color);
|
||||
if (showMessageBox)
|
||||
MessageBox.Show(result, "Fatal", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ WriteLine ] -------------------------------------------------
|
||||
|
||||
private StackFrame GetStackFrame(StackTrace trace)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (StackFrame frame in trace.GetFrames())
|
||||
{
|
||||
MethodBase method = frame.GetMethod();
|
||||
if (method.DeclaringType != typeof(XLogger))
|
||||
return frame;
|
||||
}
|
||||
|
||||
return trace.GetFrame(2);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine(ex.Message);
|
||||
return trace.GetFrame(2);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 문자열 값을 log4net 혹은 표준 출력 스트림에 출력합니다
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="value"></param>
|
||||
public string WriteLine(eXLogLevel level, object value = null, Color? color = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
StackTrace trace = new StackTrace();
|
||||
//StackFrame frame = trace.GetFrame(2);
|
||||
StackFrame frame = this.GetStackFrame(trace);
|
||||
MethodBase method = frame.GetMethod();
|
||||
Exception ex = null;
|
||||
string strMessage = string.Empty;
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
if (value is Exception)
|
||||
{
|
||||
ex = value as Exception;
|
||||
//strMessage = ex.Message;
|
||||
}
|
||||
else
|
||||
{
|
||||
strMessage = value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return WriteLine(level, strMessage, method, ex, color);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine(ex.Message);
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 문자열 값을 log4net 혹은 표준 출력 스트림에 출력합니다
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="e"></param>
|
||||
public string WriteLine(eXLogLevel level, string message, Exception e, Color? color = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
StackTrace trace = new StackTrace();
|
||||
//StackFrame frame = trace.GetFrame(2);
|
||||
StackFrame frame = this.GetStackFrame(trace);
|
||||
MethodBase method = frame.GetMethod();
|
||||
string strMessage = string.Empty;
|
||||
|
||||
strMessage = message;
|
||||
|
||||
return WriteLine(level, strMessage, method, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine(ex.Message);
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 문자열 값을 log4net 혹은 표준 출력 스트림에 출력합니다
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="method"></param>
|
||||
public string WriteLine(eXLogLevel level, string message, MethodBase method, Exception e = null, Color? color = null)
|
||||
{
|
||||
string result = string.Empty;
|
||||
try
|
||||
{
|
||||
string name = this.Name;
|
||||
string strDTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
string strClassFullName = string.Empty;
|
||||
string strClassName = string.Empty;
|
||||
string strMethod = string.Empty;
|
||||
string strLog = string.Empty;
|
||||
string strConsole = string.Empty;
|
||||
|
||||
ILog log = LogManager.GetLogger(name);
|
||||
ClearMDC();
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
StackTrace trace = new StackTrace();
|
||||
StackFrame frame = trace.GetFrame(1);
|
||||
method = frame.GetMethod();
|
||||
}
|
||||
|
||||
if (method != null && method.DeclaringType != null)
|
||||
{
|
||||
if (m_FilterTypes.Count > 0 && m_FilterTypes.Contains(method.DeclaringType) == false) return result;
|
||||
|
||||
strClassFullName = method.DeclaringType.FullName;
|
||||
strClassName = method.DeclaringType.Name;
|
||||
strMethod = method.Name;
|
||||
}
|
||||
|
||||
if (message.EndsWith(Environment.NewLine))
|
||||
message = message.Remove(message.Length - Environment.NewLine.Length);
|
||||
strLog = message;
|
||||
strConsole = string.Format(this.ControlPatternLayout, strDTime, level.ToString().ToUpper(), name, strClassFullName, strMethod, message, strClassName);
|
||||
|
||||
SetMDC(eMDCKey.Name, name);
|
||||
SetMDC(eMDCKey.Class, strClassFullName);
|
||||
SetMDC(eMDCKey.Method, strMethod);
|
||||
|
||||
result = $"{strConsole}" + (e != null ? Environment.NewLine + e.ToString() : "");
|
||||
switch (level)
|
||||
{
|
||||
case eXLogLevel.Debug:
|
||||
if (log.IsDebugEnabled) { log.Debug(strLog, e); this.WriteControl(result, color); }
|
||||
break;
|
||||
case eXLogLevel.Info:
|
||||
if (log.IsInfoEnabled) { log.Info(strLog, e); this.WriteControl(result, color); }
|
||||
break;
|
||||
case eXLogLevel.Warn:
|
||||
if (log.IsWarnEnabled) { log.Warn(strLog, e); this.WriteControl(result, color); }
|
||||
break;
|
||||
case eXLogLevel.Error:
|
||||
if (log.IsErrorEnabled) { log.Error(strLog); this.WriteControl(result, color); }
|
||||
break;
|
||||
case eXLogLevel.Fatal:
|
||||
if (log.IsFatalEnabled) { log.Fatal(strLog, e); this.WriteControl(result, color); }
|
||||
break;
|
||||
}
|
||||
|
||||
//this.DeleteRollingFiles();
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine(ex.ToString());
|
||||
return ex.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control.Text에 로그를 기록한다
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
private void WriteControl(string message, Color? color = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Control == null) return;
|
||||
if (color.Equals(Color.Transparent)) return;
|
||||
if (this.Control.InvokeRequired)
|
||||
{
|
||||
this.Control.Invoke((MethodInvoker)delegate { this.WriteControl(message, color); });
|
||||
return;
|
||||
}
|
||||
|
||||
Application.DoEvents();
|
||||
this.Control.SuspendLayout();
|
||||
if (this.Control.MaxLength <= this.Control.TextLength + message.Length)
|
||||
{
|
||||
int count = 0;
|
||||
while (this.Control.MaxLength * 0.9 <= this.Control.TextLength + message.Length)
|
||||
{
|
||||
this.Control.SelectionStart = 0;
|
||||
this.Control.SelectionLength = this.Control.GetFirstCharIndexFromLine(count + 1);
|
||||
this.Control.SelectedText = string.Empty;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
int index = this.Control.TextLength;
|
||||
this.Control.AppendText(message + Environment.NewLine);
|
||||
if (this.Control.GetType() == typeof(RichTextBox))
|
||||
{
|
||||
RichTextBox richTextBox = (RichTextBox)this.Control;
|
||||
if (color == null) color = richTextBox.ForeColor;
|
||||
|
||||
richTextBox.SelectionStart = index;
|
||||
richTextBox.SelectionLength = message.Length;
|
||||
richTextBox.SelectionColor = (Color)color;
|
||||
}
|
||||
|
||||
if (this.OnScrollToCaret)
|
||||
this.Control.ScrollToCaret();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (this.Control != null) this.Control.ResumeLayout();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ ETC ] -------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Change LogLevel
|
||||
/// </summary>
|
||||
/// <param name="level"></param>
|
||||
public void SetLevel(log4net.Core.Level level)
|
||||
{
|
||||
Logger logger = this.Logger;
|
||||
logger.Repository.Threshold = logger.Repository.LevelMap["DEBUG"];
|
||||
logger.Level = level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logger를 반환한다
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private log4net.Repository.Hierarchy.Logger GetLogger(string name = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(name)) name = this.Name;
|
||||
ILog log = LogManager.GetLogger(name);
|
||||
|
||||
log4net.Repository.Hierarchy.Logger logger = log.Logger as log4net.Repository.Hierarchy.Logger;
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RollingAppender 로그파일을 삭제합니다.
|
||||
/// </summary>
|
||||
/// <param name="interval">동작주기(분)</param>
|
||||
/// <remarks>
|
||||
/// RollingMode='Date'일 경우 동작하며,
|
||||
/// MaxSizeRollBackups 값을 보관일로 적용하여 기간이 경과된 파일들을 삭제한다
|
||||
/// </remarks>
|
||||
public void DeleteRollingFiles(int interval = 30)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DateTime.Now.Subtract(this.LastDeletedDateTime).TotalMinutes < interval) return;
|
||||
this.LastDeletedDateTime = DateTime.Now;
|
||||
|
||||
var repositories = LogManager.GetAllRepositories().FirstOrDefault();
|
||||
if (repositories == null) return;
|
||||
|
||||
foreach (IAppender appender in repositories.GetAppenders())
|
||||
{
|
||||
FileAppender fileAppender = appender as FileAppender;
|
||||
RollingFileAppender rollingAppender = appender as RollingFileAppender;
|
||||
if (rollingAppender != null)
|
||||
{
|
||||
int maxSizeRollBackups = rollingAppender.MaxSizeRollBackups;
|
||||
if (maxSizeRollBackups < 1) continue;
|
||||
|
||||
RollingMode rollingStyle = rollingAppender.RollingStyle;
|
||||
if (rollingStyle != RollingMode.Date) continue;
|
||||
|
||||
string path = System.IO.Path.GetDirectoryName(rollingAppender.File);
|
||||
DirectoryInfo directory = new DirectoryInfo(path);
|
||||
|
||||
//string pattern = this.GetDatePatten(rollingAppender.DatePattern);
|
||||
string extension = System.IO.Path.GetExtension(rollingAppender.File);
|
||||
List<FileInfo> files = directory.GetFiles($"*{extension}")
|
||||
.Where(x => DateTime.Now.Subtract(x.CreationTime).TotalDays > maxSizeRollBackups)
|
||||
.OrderBy(x => x.CreationTime).ToList();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
Trace.WriteLine($"Delete {file.FullName}");
|
||||
file.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private string GetDatePatten(string name)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string pattern = @"'([^']*)'";
|
||||
|
||||
MatchCollection matches = Regex.Matches(name, pattern);
|
||||
for (int i = 0; i < matches.Count; i++)
|
||||
{
|
||||
sb.Append(matches[i].Groups[1].Value);
|
||||
if (i + 1 < matches.Count) sb.Append("*");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string GetCallStack()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try
|
||||
{
|
||||
StackTrace trace = new StackTrace();
|
||||
for (int i = 0; i < trace.FrameCount; i++)
|
||||
{
|
||||
StackFrame frame = trace.GetFrame(i);
|
||||
MethodBase method = frame.GetMethod();
|
||||
sb.AppendLine($"{method?.DeclaringType?.Name}.{method.Name}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
168
JWH/JWH.csproj
Normal file
168
JWH/JWH.csproj
Normal file
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{004BC1F3-B24A-402D-92ED-C5FC501E915A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>JWH</RootNamespace>
|
||||
<AssemblyName>JWH</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
|
||||
<OutputPath>bin\ARM64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="JWH.SECS">
|
||||
<HintPath>..\Library\JWH.SECS.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Telerik.WinControls, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e, processorArchitecture=MSIL" />
|
||||
<Reference Include="Telerik.WinControls.ChartView, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e, processorArchitecture=MSIL" />
|
||||
<Reference Include="Telerik.WinControls.GridView, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e, processorArchitecture=MSIL" />
|
||||
<Reference Include="Telerik.WinControls.UI, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e, processorArchitecture=MSIL" />
|
||||
<Reference Include="TelerikCommon, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e, processorArchitecture=MSIL" />
|
||||
<Reference Include="TelerikExport, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e, processorArchitecture=MSIL" />
|
||||
<Reference Include="TIBCO.Rendezvous, Version=1.0.5155.23393, Culture=neutral, PublicKeyToken=1a696d1f90f6158a, processorArchitecture=AMD64">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Library\TIBCO 8.4.2\TIBCO.Rendezvous.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CONTROL\GridViewEx.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CONTROL\ListViewItemComparer.cs" />
|
||||
<Compile Include="DATA\CustomerAttributes.cs" />
|
||||
<Compile Include="DATA\DataTableBase.cs" />
|
||||
<Compile Include="EXTENSIONS\ExtensionAPI.cs" />
|
||||
<Compile Include="EXTENSIONS\ExtensionByte.cs" />
|
||||
<Compile Include="EXTENSIONS\ExtensionReflection.cs" />
|
||||
<Compile Include="EXTENSIONS\ExtensionXml.cs" />
|
||||
<Compile Include="EXTENSIONS\XLogger.cs" />
|
||||
<Compile Include="NETWORK\AsyncSocket.cs" />
|
||||
<Compile Include="NETWORK\FtpClient.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TIB\ListenerData.cs" />
|
||||
<Compile Include="TIB\ListenerInfo.cs" />
|
||||
<Compile Include="TIB\ListenerSystem.cs" />
|
||||
<Compile Include="TIB\MessageParser.cs" />
|
||||
<Compile Include="TIB\MessageValue.cs" />
|
||||
<Compile Include="TIB\ServerInfo.cs" />
|
||||
<Compile Include="TIB\TibRendezvous.cs" />
|
||||
<Compile Include="TIB\XmlData.cs" />
|
||||
<Compile Include="TIB\XmlMessage.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="log4net.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
<None Include="TIBCO.Rendezvous.netmodule">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="tibrv.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="tibrvcm.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="tibrvcmq.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="tibrvft.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
972
JWH/NETWORK/AsyncSocket.cs
Normal file
972
JWH/NETWORK/AsyncSocket.cs
Normal file
@@ -0,0 +1,972 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace JWH.NETWORK
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// AsyncSocket
|
||||
/// <para/>비동기 통신으로 개발 되었으므로, 이벤트 수신시 크로스스레드 오류가 발생할 수 있으므로 대응코드를 작성하여야 합니다.
|
||||
/// </summary>
|
||||
public class AsyncSocket : IDisposable
|
||||
{
|
||||
|
||||
#region [ Events ] ====================================================
|
||||
public delegate void AsyncSocketEventHandler(AsyncSocket sender, AsyncSocketEventArgs arg);
|
||||
|
||||
/// <summary>AsyncSocket Accept Event (Host)</summary>
|
||||
public event AsyncSocketEventHandler OnAccept;
|
||||
/// <summary>AsyncSocket Connect Event</summary>
|
||||
public event AsyncSocketEventHandler OnConnect;
|
||||
/// <summary>AsyncSocket Close Event</summary>
|
||||
public event AsyncSocketEventHandler OnClose;
|
||||
/// <summary>AsyncSocket Send Event</summary>
|
||||
public event AsyncSocketEventHandler OnSend;
|
||||
/// <summary>AsyncSocket Receive Event</summary>
|
||||
public event AsyncSocketEventHandler OnReceive;
|
||||
/// <summary>AsyncSocket Error Event</summary>
|
||||
public event AsyncSocketEventHandler OnError;
|
||||
#endregion
|
||||
|
||||
#region [ Variable ] ==================================================
|
||||
/// <summary>Socket</summary>
|
||||
private Socket m_Socket = null;
|
||||
/// <summary>Host/Remote IPAddress</summary>
|
||||
private string m_Address = string.Empty;
|
||||
/// <summary>Port</summary>
|
||||
private int m_Port = 5000;
|
||||
/// <summary>Socket Name</summary>
|
||||
private string m_Name = string.Empty;
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
/// <summary>
|
||||
/// Socket
|
||||
/// </summary>
|
||||
public Socket Socket
|
||||
{
|
||||
get { return this.m_Socket; }
|
||||
set { this.m_Socket = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Host/Remote IPAddress
|
||||
/// </summary>
|
||||
public string Address
|
||||
{
|
||||
get { return this.m_Address; }
|
||||
set { this.m_Address = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Port
|
||||
/// </summary>
|
||||
public int Port
|
||||
{
|
||||
get { return m_Port; }
|
||||
set { m_Port = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return this.m_Name; }
|
||||
set { this.m_Name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Host 연결상태
|
||||
/// </summary>
|
||||
public bool Connected
|
||||
{
|
||||
get { return (m_Socket == null ? false : m_Socket.Connected); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructors ] ==============================================
|
||||
|
||||
/// <summary>
|
||||
/// AsyncSocket
|
||||
/// </summary>
|
||||
public AsyncSocket()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AsyncSocket
|
||||
/// </summary>
|
||||
/// <param name="remoteAddress">Host</param>
|
||||
/// <param name="port">Port</param>
|
||||
public AsyncSocket(string remoteAddress, int port)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_Address = remoteAddress;
|
||||
this.m_Port = port;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AsyncSocket
|
||||
/// </summary>
|
||||
/// <param name="socket">Socket</param>
|
||||
public AsyncSocket(Socket socket)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_Socket = socket;
|
||||
try
|
||||
{
|
||||
IPEndPoint endpoint = (IPEndPoint)this.m_Socket.RemoteEndPoint;
|
||||
this.m_Address = endpoint.Address.ToString();
|
||||
this.m_Port = endpoint.Port;
|
||||
}
|
||||
catch
|
||||
{
|
||||
IPEndPoint endpoint = (IPEndPoint)this.m_Socket.LocalEndPoint;
|
||||
this.m_Address = endpoint.Address.ToString();
|
||||
this.m_Port = endpoint.Port;
|
||||
}
|
||||
|
||||
if (this.m_Socket != null && this.m_Socket.IsBound)
|
||||
{
|
||||
this.Receive();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 구성요소를 초기화합니다
|
||||
/// </summary>
|
||||
public void InitializeComponent()
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용 중인 모든 리소스를 정리합니다
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_Socket != null)
|
||||
{
|
||||
if (m_Socket.Connected == true) this.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ToString
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.m_Socket == null) return this.Name;
|
||||
|
||||
string strValue = string.Empty;
|
||||
try
|
||||
{
|
||||
strValue = string.Format("{0}:{1}", this.m_Socket.RemoteEndPoint.ToString(), this.Name);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
strValue = string.Format("{0}:{1}", this.m_Socket.LocalEndPoint.ToString(), this.Name);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
return strValue;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정한 개체 인스턴스가 동일한지를 확인합니다.
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
|
||||
AsyncSocket temp = obj as AsyncSocket;
|
||||
if (temp == null) return false;
|
||||
|
||||
if (temp.Name != this.Name) return false;
|
||||
if (temp.m_Address != this.Address) return false;
|
||||
if (temp.Port != this.Port) return false;
|
||||
if (temp.Socket != this.Socket) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 기본 해시 함수로 작동합니다.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Methods ] ===================================================
|
||||
|
||||
#region [ Raise_Event ] -----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// OnAccept 이벤트를 전단합니다.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void Raise_OnAccept(AsyncSocketEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.OnAccept?.Invoke(this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnConnect 이벤트를 전단합니다.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void Raise_OnConnect(AsyncSocketEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.OnConnect?.Invoke(this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnClose 이벤트를 전단합니다.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void Raise_OnClose(AsyncSocketEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.OnClose?.Invoke(this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnSend 이벤트를 전단합니다.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void Raise_OnSend(AsyncSocketEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.OnSend?.Invoke(this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnReceive 이벤트를 전단합니다.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void Raise_OnReceive(AsyncSocketEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.OnReceive?.Invoke(this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnError 이벤트를 전단합니다.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void Raise_OnError(AsyncSocketEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.OnError?.Invoke(this, e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Connect ] ---------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Connect
|
||||
/// </summary>
|
||||
public void Connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.m_Socket != null && this.m_Socket.Connected == true) return;
|
||||
|
||||
IPAddress[] ipAddress = Dns.GetHostAddresses(this.m_Address);
|
||||
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress[0], m_Port);
|
||||
if (this.m_Socket == null)
|
||||
{
|
||||
this.m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
this.m_Socket.ReceiveBufferSize = AsyncObject.BUFFER_SIZE;
|
||||
}
|
||||
|
||||
this.m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(this.OnConnectCallback), this.m_Socket);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connect
|
||||
/// </summary>
|
||||
/// <param name="hostAddress"></param>
|
||||
/// <param name="port"></param>
|
||||
public void Connect(string hostAddress, int port)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.m_Socket != null && this.m_Socket.Connected == true) return;
|
||||
|
||||
this.m_Address = hostAddress;
|
||||
this.m_Port = port;
|
||||
this.Connect();
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Connect Callback
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
protected void OnConnectCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket client = (Socket)ar.AsyncState;
|
||||
client.EndConnect(ar);
|
||||
|
||||
// OnConnect 이벤트를 날린다.
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
||||
this.Raise_OnConnect(arg);
|
||||
this.Receive();
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Close ] -----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Close
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.m_Socket.Connected == true)
|
||||
{
|
||||
this.m_Socket.Shutdown(SocketShutdown.Both);
|
||||
this.m_Socket.BeginDisconnect(false, new AsyncCallback(OnCloseCallback), this.m_Socket);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Socket.Close(100);
|
||||
this.m_Socket = null;
|
||||
}
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close Callback
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
protected void OnCloseCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket client = (Socket)ar.AsyncState;
|
||||
|
||||
// OnClose 이벤트를 전송한다
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
||||
this.Raise_OnClose(arg);
|
||||
|
||||
if (client.IsBound)
|
||||
{
|
||||
client.EndDisconnect(ar);
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Send ] ------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Send
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
public void Send(byte[] buffer, object tag = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_Socket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(OnSendCallback), this.m_Socket);
|
||||
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Bytes = buffer;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnSend(arg);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="size"></param>
|
||||
public void Send(byte[] buffer, int offset, int size, object tag = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_Socket.BeginSend(buffer, offset, size, 0, new AsyncCallback(OnSendCallback), this.m_Socket);
|
||||
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Bytes = buffer.Clone(offset, size);
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnSend(arg);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
public void Send(string buffer, object tag = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] byteBuffer = Encoding.ASCII.GetBytes(buffer);
|
||||
this.m_Socket.BeginSend(byteBuffer, 0, buffer.Length, 0, new AsyncCallback(this.OnSendCallback), this.m_Socket);
|
||||
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Bytes = byteBuffer;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnSend(arg);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send
|
||||
/// </summary>
|
||||
/// <param name="buffer"></param>
|
||||
public void Send(string buffer, Encoding encoding, object tag = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] byteBuffer = encoding.GetBytes(buffer);
|
||||
this.m_Socket.BeginSend(byteBuffer, 0, buffer.Length, 0, new AsyncCallback(this.OnSendCallback), this.m_Socket);
|
||||
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Bytes = byteBuffer;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnSend(arg);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
arg.Tag = tag;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send Callback
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
protected void OnSendCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket client = (Socket)ar.AsyncState;
|
||||
int bytesWritten = client.EndSend(ar);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Receive ] ---------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Recive
|
||||
/// </summary>
|
||||
public void Receive()
|
||||
{
|
||||
try
|
||||
{
|
||||
AsyncObject stateObject = new AsyncObject(this.m_Socket);
|
||||
this.m_Socket.BeginReceive(stateObject.Buffer, 0, AsyncObject.BUFFER_SIZE, 0, new AsyncCallback(this.OnReceiveCallback), stateObject);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs();
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Receive Callback
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
protected void OnReceiveCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
AsyncObject stateObject = ar.AsyncState as AsyncObject;
|
||||
Socket client = stateObject.Socket;
|
||||
int nLength = client.EndReceive(ar);
|
||||
|
||||
if (nLength == 0)
|
||||
{
|
||||
this.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
// OnReceive 이벤트를 전송한다
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
||||
arg.Bytes = stateObject.Buffer.Clone(0, nLength);
|
||||
this.Raise_OnReceive(arg);
|
||||
this.Receive();
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Listen ] ----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Listen (Host)
|
||||
/// </summary>
|
||||
/// <param name="backlog">보류 중인 연결 큐의 최대 길이입니다</param>
|
||||
public void Listen(int backlog = 100)
|
||||
{
|
||||
try
|
||||
{
|
||||
IPAddress[] ipAddress = Dns.GetHostAddresses(m_Address);
|
||||
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress[0], m_Port);
|
||||
if (this.m_Socket == null)
|
||||
{
|
||||
this.m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
this.m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||
}
|
||||
this.m_Socket.Bind(ipEndPoint);
|
||||
this.m_Socket.Listen(backlog);
|
||||
this.m_Socket.BeginAccept(new AsyncCallback(this.OnAcceptCallback), this.m_Socket);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Listen
|
||||
/// </summary>
|
||||
/// <param name="hostAddress">Host</param>
|
||||
/// <param name="port">Port</param>
|
||||
/// <param name="backlog">보류 중인 연결 큐의 최대 길이입니다</param>
|
||||
public void Listen(string hostAddress, int port, int backlog = 100)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_Address = hostAddress;
|
||||
this.m_Port = port;
|
||||
this.Listen(backlog);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Accept ] ----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Accept CallBack
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
protected void OnAcceptCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.m_Socket == null) return;
|
||||
Socket listener = (Socket)ar.AsyncState;
|
||||
if (!listener.IsBound) return;
|
||||
|
||||
Socket client = listener.EndAccept(ar);
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(client);
|
||||
this.Raise_OnAccept(arg);
|
||||
this.m_Socket.BeginAccept(new AsyncCallback(this.OnAcceptCallback), this.m_Socket);
|
||||
}
|
||||
catch (SocketException exa)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = exa;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AsyncSocketEventArgs arg = new AsyncSocketEventArgs(this.m_Socket);
|
||||
arg.Exception = ex;
|
||||
this.Raise_OnError(arg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AsyncSocket Event Argument
|
||||
/// </summary>
|
||||
public class AsyncSocketEventArgs : EventArgs
|
||||
{
|
||||
|
||||
#region [ Variable ] ==================================================
|
||||
/// <summary>Socket</summary>
|
||||
private Socket m_Socket = null;
|
||||
/// <summary>Send/Receive Data</summary>
|
||||
private byte[] m_Bytes = null;
|
||||
/// <summary>Tag</summary>
|
||||
private object m_Tag = null;
|
||||
/// <summary>Exception</summary>
|
||||
private Exception m_Exception = null;
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
/// <summary>
|
||||
/// Socket
|
||||
/// </summary>
|
||||
public Socket Socket
|
||||
{
|
||||
get { return this.m_Socket; }
|
||||
set { this.m_Socket = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send/Receive Data
|
||||
/// </summary>
|
||||
public byte[] Bytes
|
||||
{
|
||||
get { return this.m_Bytes; }
|
||||
set { this.m_Bytes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exception
|
||||
/// </summary>
|
||||
public Exception Exception
|
||||
{
|
||||
get { return this.m_Exception; }
|
||||
set { this.m_Exception = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tag
|
||||
/// </summary>
|
||||
public object Tag
|
||||
{
|
||||
get { return this.m_Tag; }
|
||||
set { this.m_Tag = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructors ] ==============================================
|
||||
|
||||
/// <summary>
|
||||
/// 생성자
|
||||
/// </summary>
|
||||
public AsyncSocketEventArgs()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 생성자
|
||||
/// </summary>
|
||||
/// <param name="socket">Socket</param>
|
||||
public AsyncSocketEventArgs(Socket socket)
|
||||
{
|
||||
m_Socket = socket;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 비동기 작업의 상태
|
||||
/// </summary>
|
||||
public class AsyncObject
|
||||
{
|
||||
|
||||
#region [ Variables ] =================================================
|
||||
/// <summary>버퍼사이즈</summary>
|
||||
public static int BUFFER_SIZE = 32768;
|
||||
/// <summary>Socket</summary>
|
||||
private Socket m_Socket;
|
||||
/// <summary>Buffer</summary>
|
||||
private byte[] m_byteBuffer;
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
/// <summary>
|
||||
/// Socket
|
||||
/// </summary>
|
||||
public Socket Socket
|
||||
{
|
||||
get { return this.m_Socket; }
|
||||
set { this.m_Socket = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 버퍼
|
||||
/// </summary>
|
||||
public byte[] Buffer
|
||||
{
|
||||
get { return this.m_byteBuffer; }
|
||||
set { this.m_byteBuffer = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructors ] ==============================================
|
||||
|
||||
/// <summary>
|
||||
/// AsyncObject
|
||||
/// </summary>
|
||||
/// <param name="socket">Socket</param>
|
||||
public AsyncObject(Socket socket)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_Socket = socket;
|
||||
this.m_byteBuffer = new byte[BUFFER_SIZE];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
305
JWH/NETWORK/FtpClient.cs
Normal file
305
JWH/NETWORK/FtpClient.cs
Normal file
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace JWH.NETWORK
|
||||
{
|
||||
|
||||
public class FtpClient
|
||||
{
|
||||
|
||||
#region [ Properties ] ------------------------------------------------
|
||||
|
||||
public string URI { get; set; }
|
||||
|
||||
public string UID { get; set; }
|
||||
|
||||
public string PWD { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ FtpClient ] -------------------------------------------------
|
||||
|
||||
public FtpClient()
|
||||
{
|
||||
}
|
||||
|
||||
public FtpClient(string uri, string uid, string pwd)
|
||||
{
|
||||
this.URI = uri;
|
||||
this.UID = uid;
|
||||
this.PWD = pwd;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ----------------------------------------------------
|
||||
|
||||
private FtpWebRequest GetFtpWebRequest(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
FtpWebRequest ftpRequest = WebRequest.Create(path) as FtpWebRequest;
|
||||
ftpRequest.Timeout = 3000;
|
||||
if (string.IsNullOrEmpty(this.UID)) ftpRequest.Credentials = new NetworkCredential();
|
||||
else ftpRequest.Credentials = new NetworkCredential(this.UID, this.PWD);
|
||||
|
||||
return ftpRequest;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetList(string path = "")
|
||||
{
|
||||
StreamReader reader = null;
|
||||
try
|
||||
{
|
||||
List<string> lstFile = new List<string>();
|
||||
|
||||
string fullPath = $"{this.URI}{path}";
|
||||
FtpWebRequest ftpRequest = this.GetFtpWebRequest(fullPath);
|
||||
//ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
|
||||
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
|
||||
|
||||
WebResponse response = ftpRequest.GetResponse();
|
||||
reader = new StreamReader(response.GetResponseStream());
|
||||
string fileInfo = reader.ReadLine();
|
||||
while (string.IsNullOrEmpty(fileInfo) == false)
|
||||
{
|
||||
object obj = this.CreateFtpObject(fileInfo);
|
||||
lstFile.Add(fileInfo);
|
||||
fileInfo = reader.ReadLine();
|
||||
}
|
||||
|
||||
return lstFile.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null) reader.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public FtpObject[] GetFtpObjects(string path = "")
|
||||
{
|
||||
StreamReader reader = null;
|
||||
string fullPath = $"{this.URI}{path}";
|
||||
try
|
||||
{
|
||||
List<FtpObject> lstObject = new List<FtpObject>();
|
||||
|
||||
FtpWebRequest ftpRequest = this.GetFtpWebRequest(fullPath);
|
||||
//ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
|
||||
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
|
||||
|
||||
WebResponse response = ftpRequest.GetResponse();
|
||||
reader = new StreamReader(response.GetResponseStream());
|
||||
string fileInfo = reader.ReadLine();
|
||||
while (string.IsNullOrEmpty(fileInfo) == false)
|
||||
{
|
||||
FtpObject obj = this.CreateFtpObject(fileInfo);
|
||||
lstObject.Add(obj);
|
||||
fileInfo = reader.ReadLine();
|
||||
}
|
||||
|
||||
return lstObject.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null) reader.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Download(string path, string localpath)
|
||||
{
|
||||
FileStream writer = null;
|
||||
Stream reader = null;
|
||||
try
|
||||
{
|
||||
string fullPath = $"{this.URI}{path}";
|
||||
FtpWebRequest ftpRequest = this.GetFtpWebRequest(fullPath);
|
||||
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
|
||||
|
||||
WebResponse response = ftpRequest.GetResponse();
|
||||
reader = response.GetResponseStream();
|
||||
|
||||
if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(localpath)) == false)
|
||||
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(localpath));
|
||||
writer = new FileStream(localpath, FileMode.Create, FileAccess.Write);
|
||||
byte[] byteBuffer = new byte[1024];
|
||||
|
||||
int byteSize = reader.Read(byteBuffer, 0, byteBuffer.Length);
|
||||
while (byteSize > 0)
|
||||
{
|
||||
writer.Write(byteBuffer, 0, byteSize);
|
||||
byteSize = reader.Read(byteBuffer, 0, byteBuffer.Length);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Error($"{this.URI}{path} --> {localpath}");
|
||||
throw ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (writer != null) writer.Close();
|
||||
if (reader != null) reader.Close();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public FtpObject CreateFtpObject(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
string strDateTime = value.Substring(0, 17).Trim();
|
||||
string strType = value.Substring(18, 11).Trim();
|
||||
string strLength = value.Substring(30, 8).Trim();
|
||||
string strName = value.Substring(39).Trim();
|
||||
|
||||
DateTime dtCreate = DateTime.MinValue;
|
||||
DateTime.TryParse(strDateTime, out dtCreate);
|
||||
long nLength = 0;
|
||||
long.TryParse(strLength, out nLength);
|
||||
|
||||
FtpObject result = null;
|
||||
if (string.Compare(strType, "<DIR>", true) == 0)
|
||||
{
|
||||
FtpDirectory ftpDirectory = new FtpDirectory();
|
||||
ftpDirectory.Name = strName;
|
||||
ftpDirectory.CreateDateTime = dtCreate;
|
||||
result = ftpDirectory;
|
||||
}
|
||||
else
|
||||
{
|
||||
FtpFile ftpFile = new FtpFile();
|
||||
ftpFile.Name = strName;
|
||||
ftpFile.Length = nLength;
|
||||
ftpFile.CreateDateTime = dtCreate;
|
||||
result = ftpFile;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FtpObject
|
||||
{
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string Path { get; set; } = string.Empty;
|
||||
|
||||
public string FullName { get { return $"{this.Path}/{this.Name}"; } }
|
||||
|
||||
public DateTime CreateDateTime { get; set; } = DateTime.MinValue;
|
||||
|
||||
public TreeNode GetTreeNode()
|
||||
{
|
||||
TreeNode node = null;
|
||||
node = new TreeNode(this.Name, 0, 0);
|
||||
node.Tag = this;
|
||||
|
||||
if (this.GetType() == typeof(FtpDirectory))
|
||||
{
|
||||
node.ImageIndex = 1;
|
||||
FtpDirectory ftpDirectory = this as FtpDirectory;
|
||||
foreach(FtpObject obj in ftpDirectory.Childs )
|
||||
{
|
||||
node.Nodes.Add(obj.GetTreeNode());
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public void Refresh(FtpClient ftpClient, int depth = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class FtpDirectory : FtpObject
|
||||
{
|
||||
|
||||
public List<FtpObject> Childs { get; set; } = new List<FtpObject>();
|
||||
|
||||
public FtpObject[] GetChilds(FtpClient ftpClient, int depth = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<FtpObject> lstChild = new List<FtpObject>();
|
||||
if (depth < 0) return lstChild.ToArray();
|
||||
|
||||
foreach (FtpObject obj in ftpClient.GetFtpObjects(this.FullName))
|
||||
{
|
||||
obj.Path = this.FullName;
|
||||
lstChild.Add(obj);
|
||||
FtpDirectory ftpDirectory = obj as FtpDirectory;
|
||||
if (ftpDirectory != null && depth > 0)
|
||||
ftpDirectory.Childs.AddRange(this.GetChilds(ftpClient, depth - 1));
|
||||
}
|
||||
|
||||
this.Childs.Clear();
|
||||
this.Childs.AddRange(lstChild.ToArray());
|
||||
|
||||
return this.Childs.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FtpFile : FtpObject
|
||||
{
|
||||
|
||||
public long Length { get; set; } = 0;
|
||||
|
||||
public FtpFile()
|
||||
{
|
||||
}
|
||||
|
||||
public FtpFile(string name, long length)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Length = length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
37
JWH/Properties/AssemblyInfo.cs
Normal file
37
JWH/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
|
||||
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
|
||||
// 이러한 특성 값을 변경하세요.
|
||||
[assembly: AssemblyTitle("JWH")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("Copyright 2024. Jungwoo.Han all rights reserved")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
|
||||
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
|
||||
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
|
||||
[assembly: Guid("004bc1f3-b24a-402d-92ed-c5fc501e915a")]
|
||||
|
||||
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
|
||||
//
|
||||
// 주 버전
|
||||
// 부 버전
|
||||
// 빌드 번호
|
||||
// 수정 버전
|
||||
//
|
||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
|
||||
// 기본값으로 할 수 있습니다.
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
|
||||
3
JWH/Properties/licenses.licx
Normal file
3
JWH/Properties/licenses.licx
Normal file
@@ -0,0 +1,3 @@
|
||||
Telerik.WinControls.UI.RadSplitContainer, Telerik.WinControls.UI, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e
|
||||
Telerik.WinControls.UI.Docking.RadDock, Telerik.WinControls.RadDock, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e
|
||||
Telerik.WinControls.Themes.VisualStudio2012DarkTheme, Telerik.WinControls.Themes.VisualStudio2012Dark, Version=2019.1.219.40, Culture=neutral, PublicKeyToken=5bb2a467cbec794e
|
||||
17
JWH/TIB/ListenerData.cs
Normal file
17
JWH/TIB/ListenerData.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using JWH;
|
||||
using TIBCO.Rendezvous;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
public class ListenerData : ListenerInfo
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
268
JWH/TIB/ListenerInfo.cs
Normal file
268
JWH/TIB/ListenerInfo.cs
Normal file
@@ -0,0 +1,268 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JWH;
|
||||
using TIBCO.Rendezvous;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
public class ListenerInfo : IDisposable
|
||||
{
|
||||
|
||||
public static int NextID = 1;
|
||||
|
||||
#region [ Event ] =====================================================
|
||||
|
||||
public delegate void OnReceivedHandler(ListenerInfo sender, MessageReceivedEventArgs args);
|
||||
|
||||
public delegate void OnEventHandler(ListenerInfo sender, TibRendezvousEventArgs args);
|
||||
|
||||
|
||||
public event OnReceivedHandler OnReceivedMessage;
|
||||
|
||||
public event OnEventHandler OnReceivedEvent;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
public int ID { get; protected set; } = 0;
|
||||
|
||||
public XLogger Logger { get; set; } = XLogger.Instance;
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
public Listener Listener { get; set; } = null;
|
||||
|
||||
public Queue Queue { get { return this?.Listener?.Queue; } }
|
||||
|
||||
protected Dispatcher Dispatcher { get; set; } = null;
|
||||
|
||||
protected Thread QueueDispatchThread { get; set; } = null;
|
||||
|
||||
protected bool QueueDispatchFlag { get; set; } = false;
|
||||
|
||||
protected double DispatchInterval { get; set; } = -1;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructor ] ===============================================
|
||||
|
||||
public ListenerInfo()
|
||||
{
|
||||
this.ID = NextID++;
|
||||
}
|
||||
|
||||
~ListenerInfo()
|
||||
{
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Dispatcher != null)
|
||||
{
|
||||
this.Dispatcher.Destroy();
|
||||
this.Dispatcher = null;
|
||||
}
|
||||
|
||||
if (this.QueueDispatchThread != null)
|
||||
{
|
||||
this.QueueDispatchFlag = false;
|
||||
if (this.QueueDispatchThread.ThreadState != ThreadState.Stopped) this.QueueDispatchThread.Abort();
|
||||
this.QueueDispatchThread = null;
|
||||
}
|
||||
|
||||
if (this.Listener != null)
|
||||
{
|
||||
this.Listener.Destroy();
|
||||
this.Listener = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ====================================================
|
||||
|
||||
protected void Raise_ReceivedData(MessageReceivedEventArgs args)
|
||||
{
|
||||
this.OnReceivedMessage?.Invoke(this, args);
|
||||
}
|
||||
|
||||
protected void Raise_ReceivedEvent(TibRendezvousEventArgs args)
|
||||
{
|
||||
this.OnReceivedEvent?.Invoke(this, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 비정상 종료시, 내부 쓰레드가 종료되지 않는다.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Dispatch()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Listener == null) return false;
|
||||
if (this.Listener.Queue == null) return false;
|
||||
if (this.QueueDispatchThread != null) return false;
|
||||
|
||||
this.Dispatcher = new Dispatcher(this.Listener.Queue);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queue.Dispatch() or Queue.TimedDispatch(interval)
|
||||
/// </summary>
|
||||
/// <param name="interval"></param>
|
||||
/// <returns></returns>
|
||||
public bool QueueDispatch(double interval = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Listener == null) return false;
|
||||
if (this.Listener.Queue == null) return false;
|
||||
if (this.Dispatcher != null) return false;
|
||||
this.DispatchInterval = interval;
|
||||
|
||||
if (this.QueueDispatchThread != null) this.QueueDispatchThread.Abort();
|
||||
this.QueueDispatchThread = new Thread(new ThreadStart(this.QueueDispatch_Threading));
|
||||
this.QueueDispatchThread.IsBackground = true;
|
||||
this.QueueDispatchThread.Start();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
protected void QueueDispatch_Threading()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Debug($"Start {this.Subject}");
|
||||
this.QueueDispatchFlag = true;
|
||||
while (this.QueueDispatchFlag)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.DispatchInterval > 0) this.Queue.TimedDispatch(this.DispatchInterval);
|
||||
else this.Queue.Dispatch();
|
||||
//this.Logger.Info($"Queue.Count is {this.Queue.Count}");
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
}
|
||||
}
|
||||
this.QueueDispatchFlag = false;
|
||||
this.QueueDispatchThread = null;
|
||||
this.Logger.Debug($"Finish");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Tread Exception...!
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ReceivedMessage(object sender, MessageReceivedEventArgs eventArgs)
|
||||
{
|
||||
this.Raise_ReceivedData(eventArgs);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
public class TibRendezvousEventArgs : EventArgs
|
||||
{
|
||||
|
||||
public Message Message { get; private set; } = null;
|
||||
|
||||
public string SendSubject { get; private set; } = string.Empty;
|
||||
|
||||
public string ReplySubject { get; private set; } = string.Empty;
|
||||
|
||||
public string Class { get; private set; } = string.Empty;
|
||||
|
||||
public string Source { get; private set; } = string.Empty;
|
||||
|
||||
public string Name { get; private set; } = string.Empty;
|
||||
|
||||
public Dictionary<string, object> Properties { get; private set; } = new Dictionary<string, object>();
|
||||
|
||||
public TibRendezvousEventArgs()
|
||||
{
|
||||
}
|
||||
|
||||
public TibRendezvousEventArgs(Message message)
|
||||
{
|
||||
this.Message = message;
|
||||
this.SendSubject = message.SendSubject;
|
||||
this.ReplySubject = message.ReplySubject;
|
||||
for (uint i = 0; i < message.FieldCount; i++)
|
||||
{
|
||||
MessageField field = message.GetFieldByIndex(i);
|
||||
if (string.Compare(field.Name, "ADV_CLASS", true) == 0) { this.Class = field.Value.ToString(); continue; }
|
||||
if (string.Compare(field.Name, "ADV_SOURCE", true) == 0) { this.Source = field.Value.ToString(); continue; }
|
||||
if (string.Compare(field.Name, "ADV_NAME", true) == 0) { this.Name = field.Value.ToString(); continue; }
|
||||
|
||||
if (field.Value?.GetType() == typeof(DateTime))
|
||||
{
|
||||
DateTime dt = (DateTime)field.Value;
|
||||
if (dt.Kind != DateTimeKind.Local)
|
||||
{
|
||||
TimeZoneInfo localZone = TimeZoneInfo.Local;
|
||||
DateTime localTime = TimeZoneInfo.ConvertTimeFromUtc(dt, TimeZoneInfo.Local);
|
||||
this.Properties[field.Name] = localTime;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this.Properties[field.Name] = field.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
//sb.Append($"[{this.SendSubject}] ");
|
||||
//if (!string.IsNullOrEmpty(this.ReplySubject)) sb.Append($"From {this.ReplySubject}: ");
|
||||
//sb.AppendLine();
|
||||
sb.Append($"ADV_CLASS='{this.Class}' ");
|
||||
sb.Append($"ADV_SOURCE='{this.Source}' ");
|
||||
sb.Append($"ADV_NAME='{this.Name}' ");
|
||||
foreach (KeyValuePair<string, object> pair in this.Properties)
|
||||
sb.Append($"({pair.Value?.GetType().Name}){pair.Key}='{pair.Value?.ToString()}' ");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
34
JWH/TIB/ListenerSystem.cs
Normal file
34
JWH/TIB/ListenerSystem.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TIBCO.Rendezvous;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
public class ListenerSystem : ListenerInfo
|
||||
{
|
||||
|
||||
public override void ReceivedMessage(object sender, MessageReceivedEventArgs eventArgs)
|
||||
{
|
||||
Message message = eventArgs.Message;
|
||||
|
||||
//StringBuilder sb = new StringBuilder();
|
||||
//sb.AppendLine($"{message.ReplySubject} to {message.SendSubject}".Trim());
|
||||
//for (uint i = 0; i < message.FieldCount; i++)
|
||||
//{
|
||||
// MessageField field = message.GetFieldByIndex(i);
|
||||
// sb.AppendLine($"> {field.Name}={field.Value}");
|
||||
//}
|
||||
//Console.WriteLine( sb.ToString() );
|
||||
|
||||
TibRendezvousEventArgs args = new TibRendezvousEventArgs(message);
|
||||
|
||||
base.Raise_ReceivedEvent(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
448
JWH/TIB/MessageParser.cs
Normal file
448
JWH/TIB/MessageParser.cs
Normal file
@@ -0,0 +1,448 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using JWH;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
public class MessageParser
|
||||
{
|
||||
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
public string SendSubject { get; set; } = string.Empty;
|
||||
|
||||
public string XmlData { get; set; } = string.Empty;
|
||||
|
||||
public bool SendRequest { get; set; } = false;
|
||||
|
||||
public string PathMessageReply { get; set; } = string.Empty;
|
||||
|
||||
public List<MessageValue> MessageValues { get; set; } = new List<MessageValue>();
|
||||
|
||||
|
||||
public MessageParser()
|
||||
{
|
||||
}
|
||||
|
||||
public MessageParser(string xmlData, bool sendRequest = false)
|
||||
{
|
||||
this.XmlData = xmlData;
|
||||
this.SendRequest = sendRequest;
|
||||
}
|
||||
|
||||
public MessageParser(string subject, string xmlData, bool sendRequest = false)
|
||||
{
|
||||
this.Subject = subject;
|
||||
this.XmlData = xmlData;
|
||||
this.SendRequest = sendRequest;
|
||||
}
|
||||
|
||||
|
||||
#region [ CreateMessage ] ----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 문자열로 XmlMessage를 생성한 후, 각 항목에 값을 설정한다
|
||||
/// </summary>
|
||||
/// <param name="xmlData"></param>
|
||||
/// <returns></returns>
|
||||
public XmlMessage CreateSendMessage(string xmlData, bool isValueSetting = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(xmlData)) return null;
|
||||
|
||||
XmlMessage xmlMessage = new XmlMessage(xmlData);
|
||||
if (isValueSetting)
|
||||
{
|
||||
this.SetMessageValue(xmlMessage.XmlData.Header);
|
||||
this.SetMessageValue(xmlMessage.XmlData.Body);
|
||||
}
|
||||
|
||||
return xmlMessage;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 응답메시지를 반환한다 (MessageName_*.xml)
|
||||
/// </summary>
|
||||
/// <param name="xmlRequest">Request Message</param>
|
||||
/// <returns>Reply Message</returns>
|
||||
public XmlMessage[] CreateSendReplyMessages(XmlMessage xmlRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<XmlMessage> lstReply = new List<XmlMessage>();
|
||||
XmlMessage xmlReply = null;
|
||||
string strReply = string.Empty;
|
||||
|
||||
// ReplyFile Processing...
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(this.PathMessageReply);
|
||||
foreach (FileInfo fileInfo in directoryInfo.GetFiles($"{xmlRequest.XmlData.MessageName}_*.xml"))
|
||||
{
|
||||
StreamReader reader = new StreamReader(fileInfo.FullName, Encoding.UTF8, true);
|
||||
strReply = reader.ReadToEnd();
|
||||
xmlReply = new XmlMessage(strReply);
|
||||
xmlReply.SetRequstMessage(xmlRequest);
|
||||
this.SetMessageValue(xmlReply.XmlData.Body, xmlRequest);
|
||||
|
||||
lstReply.Add(xmlReply);
|
||||
}
|
||||
if (lstReply.Count > 0) return lstReply.ToArray();
|
||||
|
||||
// Dynamic Processing
|
||||
if (string.Compare(xmlRequest.XmlData.MessageName, "AreYouThereRequest", true) == 0)
|
||||
xmlReply = this.CreateReply_AreYouThereRequest(xmlRequest);
|
||||
else
|
||||
xmlReply = this.CreateReply_Common(xmlRequest);
|
||||
lstReply.Add(xmlReply);
|
||||
|
||||
return lstReply.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ CreateReply ] ------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// CreateReply AreYouThereRequest
|
||||
/// </summary>
|
||||
/// <param name="xmlRequest"></param>
|
||||
/// <returns></returns>
|
||||
private XmlMessage CreateReply_AreYouThereRequest(XmlMessage xmlRequest)
|
||||
{
|
||||
if (xmlRequest == null) return null;
|
||||
|
||||
XmlMessage xmlReply = new XmlMessage(xmlRequest.XmlData.GetText());
|
||||
xmlReply.XmlData.MessageName += "Reply";
|
||||
xmlReply.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName;
|
||||
xmlReply.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName;
|
||||
|
||||
xmlReply.RequestMessage = xmlRequest;
|
||||
if (xmlRequest.SendRequestFlag) xmlReply.IsReply = true;
|
||||
|
||||
return xmlReply;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CreateReply Common
|
||||
/// </summary>
|
||||
/// <param name="xmlRequest"></param>
|
||||
/// <returns></returns>
|
||||
private XmlMessage CreateReply_Common(XmlMessage xmlRequest)
|
||||
{
|
||||
if (xmlRequest == null) return null;
|
||||
|
||||
XmlMessage xmlReply = new XmlMessage(xmlRequest.XmlData.GetText());
|
||||
xmlReply.XmlData.SendRequestFlag = false;
|
||||
xmlReply.XmlData.MessageName += "Reply";
|
||||
xmlReply.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName;
|
||||
xmlReply.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName;
|
||||
|
||||
XmlNode nodeReturn = xmlReply.XmlData.Message.CreateChildNode("return");
|
||||
nodeReturn.CreateChildNode("returncode", "0");
|
||||
nodeReturn.CreateChildNode("returnmessage", "TibSimulator");
|
||||
|
||||
xmlReply.RequestMessage = xmlRequest;
|
||||
if (xmlRequest.SendRequestFlag) xmlReply.IsReply = true;
|
||||
|
||||
return xmlReply;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ====================================================
|
||||
|
||||
/// <summary>
|
||||
/// 메시지의 각 항목에 값을 할당한다
|
||||
/// <para>Step-1. Value of srcMessage</para>
|
||||
/// <para>Step-2. Value of MessageValue</para>
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="srcMessage">RequestMessage</param>
|
||||
private void SetMessageValue(XmlNode node, XmlMessage srcMessage = null)
|
||||
{
|
||||
// MessageValue(UI)
|
||||
if (node.GetText() == string.Empty)
|
||||
{
|
||||
string name = node.Name;
|
||||
XmlAttribute attribute = node.GetAttribute("Name");
|
||||
if (attribute != null)
|
||||
{
|
||||
name = attribute.Value;
|
||||
node.Attributes.Remove(attribute);
|
||||
}
|
||||
|
||||
string srcValue = srcMessage?.XmlData.GetValue(name);
|
||||
MessageValue msgValue = this.GetMessageValue(name);
|
||||
if (string.IsNullOrEmpty(srcValue))
|
||||
{
|
||||
if (msgValue != null)
|
||||
{
|
||||
object value = string.Empty;
|
||||
if (msgValue.Format.ToUpper() == "FUNCTION") value = this.CallFunction(node, msgValue, srcMessage);
|
||||
else if (msgValue.Format.ToUpper() == "MACRO") value = this.CallMacro(node, msgValue, srcMessage);
|
||||
else value = msgValue.Value;
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
if (value.GetType() == typeof(string)) node.SetText((string)value);
|
||||
else if (value.GetType() == typeof(XmlNode[]))
|
||||
{
|
||||
foreach (XmlNode child in value as XmlNode[])
|
||||
node.AppendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
node.SetText(srcValue);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (XmlNode child in node.ChildNodes)
|
||||
{
|
||||
if (child.GetType() == typeof(XmlText)) continue;
|
||||
this.SetMessageValue(child, srcMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call Function
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="srcValue"></param>
|
||||
/// <param name="srcMessage"></param>
|
||||
/// <returns></returns>
|
||||
private object CallFunction(XmlNode node, MessageValue srcValue, XmlMessage srcMessage = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
string source = srcValue.Value;
|
||||
string name = string.Empty;
|
||||
string parameters = string.Empty;
|
||||
List<object> lstParameter = new List<object>();
|
||||
|
||||
int length = source.Length - 1;
|
||||
int indexStart = source.IndexOf('(');
|
||||
int indexEnd = source.IndexOf(')');
|
||||
if (indexStart >= 0) length = indexStart;
|
||||
|
||||
name = source.Substring(0, length);
|
||||
parameters = source.Substring(indexStart + 1, indexEnd - indexStart - 1);
|
||||
|
||||
MethodInfo methodInfo = this.GetType().GetMethod(name);
|
||||
if (methodInfo == null) return string.Empty;
|
||||
lstParameter.AddRange(this.GetMethodParameters(methodInfo, node, parameters, srcMessage));
|
||||
|
||||
object result = methodInfo.Invoke(this, lstParameter.ToArray());
|
||||
if (methodInfo.Name == "GetIncrement" && srcValue != null) srcValue.Value = $"{name}({(int)result + 1})";
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call Macro
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="srcValue"></param>
|
||||
/// <param name="srcMessage"></param>
|
||||
/// <returns></returns>
|
||||
private object CallMacro(XmlNode node, MessageValue srcValue, XmlMessage srcMessage = null)
|
||||
{
|
||||
string source = srcValue.Value;
|
||||
try
|
||||
{
|
||||
string macro = source;
|
||||
string name = string.Empty;
|
||||
string value = string.Empty;
|
||||
int indexStart = -1;
|
||||
int indexEnd = -1;
|
||||
|
||||
indexStart = macro.IndexOf('%', 0);
|
||||
while (indexStart >= 0)
|
||||
{
|
||||
indexStart = macro.IndexOf('%', indexStart);
|
||||
indexEnd = macro.IndexOf('%', indexStart + 1);
|
||||
if (indexStart < 0) break;
|
||||
name = macro.Substring(indexStart + 1, indexEnd - indexStart - 1);
|
||||
|
||||
value = string.Empty;
|
||||
if (srcMessage != null) value = srcMessage.XmlData.GetValue(name);
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
MessageValue msgValue = this.GetMessageValue(name);
|
||||
if (msgValue != null) value = msgValue.Value;
|
||||
}
|
||||
|
||||
macro = $"{macro.Substring(0, indexStart)}{value}{macro.Substring(indexEnd + 1)}";
|
||||
indexStart = 0;
|
||||
}
|
||||
|
||||
return macro;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
private object[] GetMethodParameters(MethodInfo method, XmlNode node, string arguments, XmlMessage srcMessage = null)
|
||||
{
|
||||
string[] parameters = arguments.Split(',');
|
||||
List<object> lstParameter = new List<object>();
|
||||
|
||||
string name = string.Empty;
|
||||
object value = string.Empty;
|
||||
for (int i = 0; i < method.GetParameters().Length; i++)
|
||||
{
|
||||
if (parameters[i].StartsWith("%") && parameters[i].EndsWith("%")) name = parameters[i].Replace("%", "");
|
||||
if (name.ToUpper() == "XMLNODE") { lstParameter.Add(node); continue; }
|
||||
if (name.ToUpper() == "XMLMESSAGE") { lstParameter.Add(srcMessage); continue; }
|
||||
if (srcMessage != null) value = srcMessage.XmlData.GetValue(name);
|
||||
|
||||
if (value == null || value.GetType() == typeof(string) ? string.IsNullOrEmpty((string)value) : false)
|
||||
{
|
||||
MessageValue msgValue = this.GetMessageValue(name);
|
||||
if (msgValue != null)
|
||||
{
|
||||
if (msgValue.Format.ToUpper() == "FUNCTION") value = this.CallFunction(node, msgValue, srcMessage);
|
||||
else if (msgValue.Format.ToUpper() == "MACRO") value = this.CallMacro(node, msgValue, srcMessage);
|
||||
else value = msgValue.Value;
|
||||
}
|
||||
}
|
||||
if (value == null) value = parameters[i];
|
||||
|
||||
var obj = Convert.ChangeType(value, method.GetParameters()[i].ParameterType);
|
||||
|
||||
lstParameter.Add(obj);
|
||||
}
|
||||
|
||||
return lstParameter.ToArray();
|
||||
}
|
||||
|
||||
private MessageValue GetMessageValue(string name)
|
||||
{
|
||||
return this.MessageValues.Where(item => item.Name.ToUpper() == name.ToUpper()).FirstOrDefault();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Function Method ] ============================================
|
||||
|
||||
public string GetDateTime()
|
||||
{
|
||||
return DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||
}
|
||||
|
||||
public string GetTransactionID()
|
||||
{
|
||||
return Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
public string GetIPAddress()
|
||||
{
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
public object[] GetPanelList(XmlNode node, string lotID, int qty)
|
||||
{
|
||||
List<XmlNode> lstPanel = new List<XmlNode>();
|
||||
for (int i = qty; i > 0; i--)
|
||||
{
|
||||
XmlNode panelInfo = node.OwnerDocument.CreateNode("element", "PANELINFO", "");
|
||||
XmlNode panelID = node.OwnerDocument.CreateNode("element", "PANELID", "");
|
||||
panelID.SetText($"{lotID}_{i.ToString("00")}");
|
||||
XmlNode panelSeq = node.OwnerDocument.CreateNode("element", "PANELSEQ", "");
|
||||
panelSeq.SetText($"{i}");
|
||||
panelInfo.AppendChild(panelID);
|
||||
panelInfo.AppendChild(panelSeq);
|
||||
lstPanel.Add(panelInfo);
|
||||
}
|
||||
|
||||
return lstPanel.ToArray();
|
||||
}
|
||||
|
||||
public object[] GetChilds(XmlNode node, XmlMessage srcMessage)
|
||||
{
|
||||
if (srcMessage == null) return null;
|
||||
|
||||
List<XmlNode> lstChilid = new List<XmlNode>();
|
||||
XmlNode xmlNode = srcMessage.XmlData.GetNode(node.Name);
|
||||
foreach (XmlNode child in xmlNode.ChildNodes)
|
||||
{
|
||||
XmlNode importNode = node.OwnerDocument.ImportNode(child, true);
|
||||
node.AppendChild(importNode);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int GetIncrement(Int32 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public string ChangeLotID()
|
||||
{
|
||||
MessageValue msgValueText = this.GetMessageValue("LotText");
|
||||
MessageValue msgValueSeq = this.GetMessageValue("LotSeq");
|
||||
MessageValue msgValueID = this.GetMessageValue("LotID");
|
||||
if (msgValueText == null || msgValueSeq == null || msgValueID == null) return String.Empty;
|
||||
|
||||
int seq = 0;
|
||||
int.TryParse(msgValueSeq.Value, out seq);
|
||||
string value = $"{msgValueText.Value}{seq.ToString("00")}";
|
||||
|
||||
msgValueID.Value = value;
|
||||
msgValueSeq.Value = (seq + 1).ToString();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public string ChangeCarrierID()
|
||||
{
|
||||
MessageValue msgValueText = this.GetMessageValue("CarrierText");
|
||||
MessageValue msgValueSeq = this.GetMessageValue("CarrierSeq");
|
||||
MessageValue msgValueID = this.GetMessageValue("CarrierID");
|
||||
if (msgValueText == null || msgValueSeq == null || msgValueID == null) return String.Empty;
|
||||
|
||||
int seq = 0;
|
||||
int.TryParse(msgValueSeq.Value, out seq);
|
||||
string value = $"{msgValueText.Value}{seq.ToString("00")}";
|
||||
|
||||
msgValueID.Value = value;
|
||||
msgValueSeq.Value = (seq + 1).ToString();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
49
JWH/TIB/MessageValue.cs
Normal file
49
JWH/TIB/MessageValue.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using JWH;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
public class MessageValue
|
||||
{
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string Value { get; set; } = string.Empty;
|
||||
|
||||
public string Format { get; set; } = string.Empty;
|
||||
|
||||
public List<string> Values { get; set; } = new List<string>();
|
||||
|
||||
public MethodInfo Method { get; set; } = null;
|
||||
|
||||
public List<string> Parameters { get; set; } = new List<string>();
|
||||
|
||||
public MessageValue()
|
||||
{
|
||||
}
|
||||
|
||||
public MessageValue(XmlNode node)
|
||||
{
|
||||
try
|
||||
{
|
||||
node.PropertiesCopyAttribute(this);
|
||||
this.Value = node.InnerText;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Name}={this.Value}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
65
JWH/TIB/ServerInfo.cs
Normal file
65
JWH/TIB/ServerInfo.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using TIBCO.Rendezvous;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Rendezvous 연결정보
|
||||
/// </summary>
|
||||
public class ServerInfo
|
||||
{
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
public TransportType TransportType { get; set; } = TransportType.Reliable;
|
||||
|
||||
public string GUID { get; protected set; } = string.Empty;
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string Service { get; set; } = string.Empty;
|
||||
|
||||
public string Daemon { get; set; } = string.Empty;
|
||||
|
||||
public string Network { get; set; } = string.Empty;
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
public string CMName { get; set; } = string.Empty;
|
||||
|
||||
public bool RequestOld { get; set; } = false;
|
||||
|
||||
public string LedgerName { get; set; } = string.Empty;
|
||||
|
||||
public bool SyncLedger { get; set; } = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructor ] ===============================================
|
||||
|
||||
public ServerInfo()
|
||||
{
|
||||
this.GUID = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
public ServerInfo(string server, string service, string daemon, string network, string subject) : this()
|
||||
{
|
||||
this.Name = server;
|
||||
this.Service = service;
|
||||
this.Daemon = daemon;
|
||||
this.Network = network;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
public enum TransportType
|
||||
{
|
||||
Reliable = 1,
|
||||
Certiry = 2,
|
||||
Distributed = 3,
|
||||
}
|
||||
|
||||
}
|
||||
956
JWH/TIB/TibRendezvous.cs
Normal file
956
JWH/TIB/TibRendezvous.cs
Normal file
@@ -0,0 +1,956 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using TIBCO.Rendezvous;
|
||||
using Message = TIBCO.Rendezvous.Message;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
public class TibRendezvous
|
||||
{
|
||||
|
||||
#region [ Static ] ====================================================
|
||||
|
||||
private static bool IsOpen { get; set; } = false;
|
||||
|
||||
public static void Open(XLogger logger = null)
|
||||
{
|
||||
if (IsOpen) return;
|
||||
try
|
||||
{
|
||||
IsOpen = true;
|
||||
if (logger == null) logger = XLogger.Instance;
|
||||
logger.Info($"TIBCO.Rendezvous.Environment.Open()");
|
||||
TIBCO.Rendezvous.Environment.Open();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (logger != null) logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Close(XLogger logger = null)
|
||||
{
|
||||
if (!IsOpen) return;
|
||||
try
|
||||
{
|
||||
IsOpen = false;
|
||||
if (logger == null) logger = XLogger.Instance;
|
||||
logger.Info($"TIBCO.Rendezvous.Environment.Close()");
|
||||
TIBCO.Rendezvous.Environment.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (logger != null) logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Event ] =====================================================
|
||||
|
||||
private delegate void ServiceStartHandler();
|
||||
|
||||
public delegate void OnTransportHandler(TibRendezvous sender, XmlMessage xmlMessage);
|
||||
|
||||
public delegate void OnListenerHandler(Listener sender, XmlMessage xmlMessage);
|
||||
|
||||
public delegate void OnListenerInfoHandler(ListenerInfo sender, XmlMessage xmlMessage);
|
||||
|
||||
public delegate void OnListenerInfoEventHandler(ListenerInfo sender, TibRendezvousEventArgs args);
|
||||
|
||||
public delegate void OnExceptionHandler(TibRendezvous sender, XmlMessage xmlMessage, Exception ex);
|
||||
|
||||
/// <summary>
|
||||
/// Communication Started
|
||||
/// </summary>
|
||||
public event EventHandler OnStarted;
|
||||
|
||||
/// <summary>
|
||||
/// Communication Stoped
|
||||
/// </summary>
|
||||
public event EventHandler OnStoped;
|
||||
|
||||
/// <summary>
|
||||
/// Message Send
|
||||
/// </summary>
|
||||
public event OnTransportHandler OnSend;
|
||||
|
||||
/// <summary>
|
||||
/// Message Sent
|
||||
/// </summary>
|
||||
public event OnTransportHandler OnSent;
|
||||
|
||||
/// <summary>
|
||||
/// Message Received
|
||||
/// </summary>
|
||||
public event OnListenerInfoHandler OnReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Timeout Exception(SendRequest, SendReply)
|
||||
/// </summary>
|
||||
public event OnExceptionHandler OnTimeout;
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Rendezvous Event
|
||||
/// </summary>
|
||||
public event OnListenerInfoEventHandler OnEvent;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Rendezvous.Variable ] =======================================
|
||||
|
||||
/// <summary>
|
||||
/// Rendezvous Server Information(서버 이상 발생시, 환형구조로 다음 서버로 연결한다)
|
||||
/// </summary>
|
||||
public List<ServerInfo> ServerInfos { get; protected set; } = new List<ServerInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Current Rendezvous Server Information
|
||||
/// </summary>
|
||||
public ServerInfo ServerInfo { get; protected set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Transport
|
||||
/// </summary>
|
||||
public Transport Transport { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Rendezvous Listener Information
|
||||
/// </summary>
|
||||
public List<ListenerInfo> Listeners { get; protected set; } = new List<ListenerInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Rendezvous Listener Information (System Event)
|
||||
/// </summary>
|
||||
public ListenerSystem ListenerSystem { get; set; } = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Variable ] ==================================================
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
/// <summary>
|
||||
/// Logger
|
||||
/// </summary>
|
||||
public XLogger Logger { get; set; } = XLogger.Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 이벤트 보고시, Invoke 처리를 위한 상위객체
|
||||
/// </summary>
|
||||
public Control Parent { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Message 전송시, Thread 방식을 사용할 것인지를 설정한다
|
||||
/// </summary>
|
||||
public bool UseThreadSend { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 수신된 SendRequest 메시지를 보관한다
|
||||
/// </summary>
|
||||
public Dictionary<string, XmlMessage> SendRequestMessages { get; protected set; } = new Dictionary<string, XmlMessage>();
|
||||
|
||||
/// <summary>
|
||||
/// SendRequest 수신후, SendReply 전송시간 (기본값: 30초)
|
||||
/// </summary>
|
||||
[DefaultValue(30)]
|
||||
public int SendRequestTime { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// SendRequest 전송후, SendReply 메시지 수신시간 (기본값: 30초)
|
||||
/// </summary>
|
||||
[DefaultValue(30)]
|
||||
public int SendReplyTime { get; set; } = 30;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructor ] ===============================================
|
||||
|
||||
public TibRendezvous()
|
||||
{
|
||||
}
|
||||
|
||||
public TibRendezvous(XLogger logger = null)
|
||||
{
|
||||
this.Logger = logger;
|
||||
}
|
||||
|
||||
public TibRendezvous(ServerInfo serverInfo, XLogger logger = null) : this()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger = logger;
|
||||
this.ServerInfo = serverInfo;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Raise_Events ] ==============================================
|
||||
|
||||
private void Raise_OnStarted()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.OnStarted == null) return;
|
||||
if (this.Parent != null && this.Parent.InvokeRequired)
|
||||
this.Parent.BeginInvoke(new EventHandler(this.OnStarted), this, new EventArgs());
|
||||
else
|
||||
this.OnStarted?.Invoke(this, new EventArgs());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void Raise_OnStoped()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.OnStoped == null) return;
|
||||
if (this.Parent != null && this.Parent.InvokeRequired)
|
||||
this.Parent.BeginInvoke(new EventHandler(this.OnStoped), this, new EventArgs());
|
||||
else
|
||||
this.OnStoped?.Invoke(this, new EventArgs());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void Raise_OnSend(XmlMessage xmlMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.OnSend == null) return;
|
||||
if (this.Parent != null && this.Parent.InvokeRequired)
|
||||
this.Parent.BeginInvoke(new OnTransportHandler(this.OnSend), this, xmlMessage);
|
||||
else
|
||||
this.OnSend?.Invoke(this, xmlMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void Raise_OnSent(XmlMessage xmlMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.SendRequestMessage_Remove(xmlMessage);
|
||||
|
||||
if (this.OnSent == null) return;
|
||||
if (this.Parent != null && this.Parent.InvokeRequired)
|
||||
this.Parent.BeginInvoke(new OnTransportHandler(this.OnSent), this, xmlMessage);
|
||||
else
|
||||
this.OnSent?.Invoke(this, xmlMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void Raise_OnReceived(ListenerInfo sender, XmlMessage xmlMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Info($"SendSubject='{xmlMessage.SendSubject}', ReplySubject='{xmlMessage.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
|
||||
|
||||
if (this.OnReceived == null) return;
|
||||
if (this.Parent != null && this.Parent.InvokeRequired)
|
||||
this.Parent.BeginInvoke(new OnListenerInfoHandler(this.OnReceived), sender, xmlMessage);
|
||||
else
|
||||
this.OnReceived?.Invoke(sender, xmlMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void Raise_OnEvent(ListenerInfo sender, TibRendezvousEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.OnEvent == null) return;
|
||||
if (this.Parent != null && this.Parent.InvokeRequired)
|
||||
this.Parent.BeginInvoke(new OnListenerInfoEventHandler(this.OnEvent), sender, args);
|
||||
else
|
||||
this.OnEvent?.Invoke(sender, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void Raise_OnTimeout(XmlMessage xmlMessage, Exception ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.OnTimeout == null) return;
|
||||
if (this.Parent != null && this.Parent.InvokeRequired)
|
||||
this.Parent.BeginInvoke(new OnExceptionHandler(this.OnTimeout), this, xmlMessage, ex);
|
||||
else
|
||||
this.OnTimeout?.Invoke(this, xmlMessage, ex);
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
throw ex1;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Public Method ] =============================================
|
||||
|
||||
/// <summary>
|
||||
/// Communication Start
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Info();
|
||||
this.NextServerInfo();
|
||||
if (this.ServerInfo == null) return;
|
||||
|
||||
TibRendezvous.Open();
|
||||
ServiceStartHandler startMethod = null;
|
||||
switch (this.ServerInfo.TransportType)
|
||||
{
|
||||
case TransportType.Reliable: startMethod = this.RMServiceStart; break;
|
||||
case TransportType.Certiry: startMethod = this.CMServiceStart; break;
|
||||
case TransportType.Distributed: startMethod = this.DQServiceStart; break;
|
||||
}
|
||||
|
||||
startMethod();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Communication Start
|
||||
/// </summary>
|
||||
public void Restart()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Info();
|
||||
if (this.ServerInfo == null) this.NextServerInfo();
|
||||
if (this.ServerInfo == null) return;
|
||||
|
||||
TibRendezvous.Open();
|
||||
ServiceStartHandler startMethod = null;
|
||||
switch (this.ServerInfo.TransportType)
|
||||
{
|
||||
case TransportType.Reliable: startMethod = this.RMServiceStart; break;
|
||||
case TransportType.Certiry: startMethod = this.CMServiceStart; break;
|
||||
case TransportType.Distributed: startMethod = this.DQServiceStart; break;
|
||||
}
|
||||
|
||||
startMethod();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
this.Logger.Info();
|
||||
this.ServiceStop();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ====================================================
|
||||
|
||||
/// <summary>
|
||||
/// RM ServiceStart(Reliable Message)
|
||||
/// </summary>
|
||||
private void RMServiceStart()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.ServiceStop();
|
||||
this.Logger.Info();
|
||||
|
||||
this.Logger.Info($"NetTransport({this.ServerInfo.Service}, {this.ServerInfo.Network}, {this.ServerInfo.Daemon})");
|
||||
NetTransport netTransport = new NetTransport(this.ServerInfo.Service, this.ServerInfo.Network, this.ServerInfo.Daemon);
|
||||
this.Transport = netTransport;
|
||||
|
||||
#region [ Event Listener : Failover ]
|
||||
{
|
||||
ListenerSystem listenerSys = new ListenerSystem();
|
||||
listenerSys.Name = "SYSTEM";
|
||||
listenerSys.Subject = $"_RV.*.*.*.*";
|
||||
this.ListenerSystem = listenerSys;
|
||||
|
||||
Queue queue = new Queue();
|
||||
queue.Name = listenerSys.Name;
|
||||
Listener listener = new Listener(queue, listenerSys.ReceivedMessage, this.Transport, listenerSys.Subject, null);
|
||||
this.Logger.Info($"Listener({queue.GetType().Name}, ReceivedMessage, {listener?.Transport.GetType().Name}, {listener.Subject}, null)");
|
||||
listenerSys.Logger = this.Logger;
|
||||
listenerSys.Listener = listener;
|
||||
listenerSys.OnReceivedMessage += this.OnReceivedMessage;
|
||||
listenerSys.OnReceivedEvent += this.OnReceivedEvent;
|
||||
listenerSys.QueueDispatch();
|
||||
}
|
||||
#endregion
|
||||
|
||||
foreach (ListenerInfo listenerInfo in this.Listeners)
|
||||
{
|
||||
if (string.IsNullOrEmpty(netTransport.Description)) netTransport.Description = $"{listenerInfo.Subject}";
|
||||
|
||||
Queue queue = new Queue();
|
||||
queue.Name = listenerInfo.Name;
|
||||
Listener listener = new Listener(queue, listenerInfo.ReceivedMessage, this.Transport, listenerInfo.Subject, null);
|
||||
this.Logger.Info($"Listener({queue.GetType().Name}, ReceivedMessage, {listener?.Transport.GetType().Name}, {listener.Subject}, null)");
|
||||
listenerInfo.Logger = this.Logger;
|
||||
listenerInfo.Listener = listener;
|
||||
listenerInfo.OnReceivedMessage += this.OnReceivedMessage;
|
||||
listenerInfo.OnReceivedEvent += this.OnReceivedEvent;
|
||||
listenerInfo.QueueDispatch();
|
||||
}
|
||||
|
||||
this.Raise_OnStarted();
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CM ServiceStart(Certiry Message)
|
||||
/// </summary>
|
||||
private void CMServiceStart()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.ServiceStop();
|
||||
this.Logger.Info();
|
||||
|
||||
this.Logger.Info($"NetTransport({this.ServerInfo.Service}, {this.ServerInfo.Network}, {this.ServerInfo.Daemon})");
|
||||
NetTransport netTransport = new NetTransport(this.ServerInfo.Service, this.ServerInfo.Network, this.ServerInfo.Daemon);
|
||||
//this.Transport = netTransport;
|
||||
|
||||
this.Logger.Info($"CMTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
|
||||
CMTransport cmTransport = new CMTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
|
||||
//this.Logger.Info($"CMTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
|
||||
//CMTransport cmTransport = new CMTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
|
||||
this.Transport = cmTransport;
|
||||
|
||||
#region [ Event Listener ]
|
||||
{
|
||||
ListenerSystem listenerSys = new ListenerSystem();
|
||||
listenerSys.Name = "SYSTEM";
|
||||
listenerSys.Subject = $"_RV.*.*.*.*";
|
||||
this.ListenerSystem = listenerSys;
|
||||
|
||||
Queue queue = new Queue();
|
||||
Listener listener = new Listener(queue, listenerSys.ReceivedMessage, netTransport, listenerSys.Subject, null);
|
||||
this.Logger.Info($"Listener(Queue[{queue.Name}], ReceivedMessage, {listener.Transport.GetType().ToString()}, {listener.Subject}, null)");
|
||||
listenerSys.Listener = listener;
|
||||
listenerSys.OnReceivedMessage += this.OnReceivedMessage;
|
||||
listenerSys.OnReceivedEvent += this.OnReceivedEvent;
|
||||
listenerSys.Dispatch();
|
||||
}
|
||||
#endregion
|
||||
|
||||
foreach (ListenerInfo listenerInfo in this.Listeners)
|
||||
{
|
||||
Queue queue = new Queue();
|
||||
CMListener listener = new CMListener(queue, listenerInfo.ReceivedMessage, cmTransport, listenerInfo.Subject, null);
|
||||
this.Logger.Info($"CMListener(Queue[{queue.Name}], ReceivedMessage, {listener.Transport.GetType().ToString()}, {listener.Subject}, null)");
|
||||
listenerInfo.Listener = listener;
|
||||
listenerInfo.OnReceivedMessage += this.OnReceivedMessage;
|
||||
listenerInfo.OnReceivedEvent += this.OnReceivedEvent;
|
||||
listenerInfo.Dispatch();
|
||||
}
|
||||
|
||||
this.Raise_OnStarted();
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Distributed ServiceStart(Distributed Queue)
|
||||
/// </summary>
|
||||
private void DQServiceStart()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.ServiceStop();
|
||||
this.Logger.Info();
|
||||
|
||||
this.Logger.Info($"NetTransport({this.ServerInfo.Service}, {this.ServerInfo.Network}, {this.ServerInfo.Daemon})");
|
||||
NetTransport netTransport = new NetTransport(this.ServerInfo.Service, this.ServerInfo.Network, this.ServerInfo.Daemon);
|
||||
this.Transport = netTransport;
|
||||
|
||||
//this.Logger.Info($"CMTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
|
||||
//CMTransport cmTransport = new CMTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
|
||||
//this.Transport = cmTransport;
|
||||
|
||||
this.Logger.Info($"CMQueueTransport(CMTransport, {this.ServerInfo.CMName})");
|
||||
CMQueueTransport cmqTransport = new CMQueueTransport(netTransport, this.ServerInfo.CMName, 1, 5, 1, 1.0, 1.5);
|
||||
//this.Logger.Info($"CMQueueTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
|
||||
//CMQueueTransport cmqTransport = new CMQueueTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
|
||||
|
||||
#region [ Event Listener ]
|
||||
{
|
||||
ListenerSystem listenerSys = new ListenerSystem();
|
||||
listenerSys.Name = "SYSTEM";
|
||||
listenerSys.Subject = $"_RV.*.*.*.*";
|
||||
this.ListenerSystem = listenerSys;
|
||||
|
||||
Queue queue = new Queue();
|
||||
Listener listener = new Listener(queue, listenerSys.ReceivedMessage, netTransport, listenerSys.Subject, null);
|
||||
this.Logger.Info($"{listener.GetType().Name}(Queue[{queue.Name}], ReceivedMessage, {listener.Transport.GetType().ToString()}, {listener.Subject}, null)");
|
||||
listenerSys.Listener = listener;
|
||||
listenerSys.OnReceivedMessage += this.OnReceivedMessage;
|
||||
listenerSys.OnReceivedEvent += this.OnReceivedEvent;
|
||||
listenerSys.Dispatch();
|
||||
}
|
||||
#endregion
|
||||
|
||||
foreach (ListenerInfo listenerInfo in this.Listeners)
|
||||
{
|
||||
Queue queue = new Queue();
|
||||
CMListener cmListener = new CMListener(queue, listenerInfo.ReceivedMessage, cmqTransport, listenerInfo.Subject, null);
|
||||
this.Logger.Info($"{cmListener.GetType().Name}(Queue[{queue.Name}], ReceivedMessage, {cmListener.Transport.GetType().ToString()}, {cmListener.Subject}, null)");
|
||||
listenerInfo.Listener = cmListener;
|
||||
listenerInfo.OnReceivedMessage += this.OnReceivedMessage;
|
||||
listenerInfo.OnReceivedEvent += this.OnReceivedEvent;
|
||||
listenerInfo.Dispatch();
|
||||
}
|
||||
|
||||
this.Raise_OnStarted();
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ServiceStop
|
||||
/// </summary>
|
||||
private void ServiceStop()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Info();
|
||||
|
||||
if (this.ListenerSystem != null)
|
||||
{
|
||||
this.ListenerSystem.Listener?.Transport?.Destroy();
|
||||
this.ListenerSystem.OnReceivedMessage -= this.OnReceivedMessage;
|
||||
this.ListenerSystem.OnReceivedEvent -= this.OnReceivedEvent;
|
||||
this.ListenerSystem.Dispose();
|
||||
}
|
||||
|
||||
foreach(ListenerInfo listenerInfo in this.Listeners)
|
||||
{
|
||||
this.Logger.Debug($"Listener[{listenerInfo.Subject}].Dispose");
|
||||
listenerInfo.Listener?.Transport?.Destroy();
|
||||
listenerInfo.OnReceivedMessage -= this.OnReceivedMessage;
|
||||
listenerInfo.OnReceivedEvent -= this.OnReceivedEvent;
|
||||
listenerInfo.Dispose();
|
||||
}
|
||||
|
||||
if (this.Transport != null)
|
||||
{
|
||||
this.Logger.Debug($"Transport.Destroy()");
|
||||
this.Transport.Destroy();
|
||||
this.Transport = null;
|
||||
|
||||
this.Raise_OnStoped();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received Data(XmlData)
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="eventArgs"></param>
|
||||
public void OnReceivedMessage(ListenerInfo sender, MessageReceivedEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
Listener listener = sender.Listener;
|
||||
Message message = args.Message;
|
||||
XmlMessage xmlMessage = new XmlMessage(message);
|
||||
this.SendRequestMessage_Add(xmlMessage);
|
||||
|
||||
this.Raise_OnReceived(sender, xmlMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add SendRequestMessage
|
||||
/// </summary>
|
||||
/// <param name="xmlMessage"></param>
|
||||
private void SendRequestMessage_Add(XmlMessage xmlMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(xmlMessage.XmlData.TransactionID)) return;
|
||||
if (this.SendRequestMessages == null) return;
|
||||
if (this.SendRequestMessages.ContainsKey(xmlMessage.XmlData.TransactionID)) return;
|
||||
|
||||
bool isAdd = false;
|
||||
// 1. SendRequest() --> SendReply()
|
||||
if (!string.IsNullOrEmpty(xmlMessage.Message.ReplySubject)) isAdd = true;
|
||||
// 2. SendRequestFlag is True --> Send()
|
||||
//if (xmlMessage.SendRequestFlag) isAdd = true;
|
||||
if (isAdd == false) return;
|
||||
|
||||
this.SendRequestMessages.Add(xmlMessage.XmlData.TransactionID, xmlMessage);
|
||||
xmlMessage.OnTimeOver += this.SendRequest_OnTimeover;
|
||||
xmlMessage.TimerStart(this.SendRequestTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove SendRequestMessage
|
||||
/// </summary>
|
||||
/// <param name="xmlMessage"></param>
|
||||
private void SendRequestMessage_Remove(XmlMessage xmlMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(xmlMessage.XmlData.TransactionID)) return;
|
||||
if (this.SendRequestMessages == null) return;
|
||||
if (!this.SendRequestMessages.ContainsKey(xmlMessage.XmlData.TransactionID)) return;
|
||||
|
||||
XmlMessage message = this.SendRequestMessages[xmlMessage.XmlData.TransactionID];
|
||||
message.OnTimeOver -= this.SendRequest_OnTimeover;
|
||||
message.TimerStop();
|
||||
this.SendRequestMessages.Remove(xmlMessage.XmlData.TransactionID);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SendRequest 수신후, SendReply를 전송하지 않았을 경우 호출된다
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void SendRequest_OnTimeover(object sender, EventArgs e)
|
||||
{
|
||||
XmlMessage xmlMessage = sender as XmlMessage;
|
||||
if (xmlMessage == null) return;
|
||||
if (this.SendRequestMessages.ContainsKey(xmlMessage.XmlData.TransactionID))
|
||||
this.SendRequestMessages.Remove(xmlMessage.XmlData.TransactionID);
|
||||
|
||||
this.Raise_OnTimeout(xmlMessage, new Exception(Source.S10001) { Source = "S10001" });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received Event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
public void OnReceivedEvent(ListenerInfo sender, TibRendezvousEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Debug(args.ToString());
|
||||
this.Raise_OnEvent(sender, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ServerInfo에 접속정보를 할당한다
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private ServerInfo NextServerInfo()
|
||||
{
|
||||
if (this.ServerInfos.Count == 0) return null;
|
||||
if (this.ServerInfo == null)
|
||||
{
|
||||
this.ServerInfo = this.ServerInfos[0];
|
||||
return this.ServerInfo;
|
||||
}
|
||||
|
||||
int index = this.ServerInfos.IndexOf(this.ServerInfo);
|
||||
if (index == -1) index = 0;
|
||||
else index += 1;
|
||||
|
||||
if (index >= this.ServerInfos.Count) index = 0;
|
||||
this.ServerInfo = this.ServerInfos[index];
|
||||
|
||||
return this.ServerInfo;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ SendMessage ] ===============================================
|
||||
|
||||
public XmlMessage SendMessage(XmlMessage xmlMessage, OnTransportHandler callback = null)
|
||||
{
|
||||
XmlMessage response = null;
|
||||
try
|
||||
{
|
||||
if (xmlMessage == null) return response;
|
||||
|
||||
if (xmlMessage.IsReply && !string.IsNullOrEmpty(xmlMessage?.RequestMessage?.ReplySubject)) this.SendReply(xmlMessage, callback);
|
||||
else if (xmlMessage.SendRequestFlag) response = this.SendRequest(xmlMessage, callback);
|
||||
else this.Send(xmlMessage, callback);
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public XmlMessage SendRequest(XmlMessage xmlMessage, OnTransportHandler callback = null)
|
||||
{
|
||||
XmlMessage xmlResponse = null;
|
||||
try
|
||||
{
|
||||
xmlMessage.SendRequestFlag = true;
|
||||
Message message = xmlMessage.Message;
|
||||
|
||||
this.Raise_OnSend(xmlMessage);
|
||||
if (this.UseThreadSend)
|
||||
{
|
||||
Task.Factory.StartNew(delegate ()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
|
||||
Message response = this.Transport.SendRequest(message, this.SendReplyTime);
|
||||
this.Raise_OnSent(xmlMessage);
|
||||
if (response == null)
|
||||
{
|
||||
this.Raise_OnTimeout(xmlMessage, new Exception(Source.S10002) { Source = "S10002" });
|
||||
return;
|
||||
}
|
||||
|
||||
xmlResponse = new XmlMessage(response) { RequestMessage = xmlMessage, IsReply = true };
|
||||
this.Raise_OnReceived(null, xmlResponse);
|
||||
if (callback != null) callback(this, xmlResponse);
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
|
||||
Message response = this.Transport.SendRequest(message, this.SendReplyTime);
|
||||
this.Raise_OnSent(xmlMessage);
|
||||
if (response == null)
|
||||
{
|
||||
this.Raise_OnTimeout(xmlMessage, new Exception(Source.S10002) { Source = "S10002" });
|
||||
return xmlResponse;
|
||||
}
|
||||
|
||||
xmlResponse = new XmlMessage(response) { RequestMessage = xmlMessage, IsReply = true };
|
||||
this.Raise_OnReceived(null, xmlResponse);
|
||||
if (callback != null) callback(this, xmlResponse);
|
||||
}
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return xmlResponse;
|
||||
}
|
||||
|
||||
public void SendReply(XmlMessage xmlMessage, OnTransportHandler callback = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Message reply = xmlMessage.Message;
|
||||
XmlMessage request = xmlMessage.RequestMessage;
|
||||
|
||||
this.Raise_OnSend(xmlMessage);
|
||||
if (this.UseThreadSend)
|
||||
{
|
||||
Task.Factory.StartNew(delegate ()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Logger.Debug($"SendSubject='{reply.SendSubject}', ReplySubject='{reply.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
|
||||
this.Transport.SendReply(reply, request.Message);
|
||||
this.Raise_OnSent(xmlMessage);
|
||||
if (callback != null) callback(this, xmlMessage);
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Logger.Debug($"SendSubject='{reply.SendSubject}', ReplySubject='{reply.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
|
||||
this.Transport.SendReply(reply, request.Message);
|
||||
this.Raise_OnSent(xmlMessage);
|
||||
if (callback != null) callback(this, xmlMessage);
|
||||
}
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void Send(XmlMessage xmlMessage, OnTransportHandler callback = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Message message = xmlMessage.Message;
|
||||
|
||||
this.Raise_OnSend(xmlMessage);
|
||||
if (this.UseThreadSend)
|
||||
{
|
||||
try
|
||||
{
|
||||
Task.Factory.StartNew(delegate ()
|
||||
{
|
||||
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
|
||||
this.Transport.Send(message);
|
||||
this.Raise_OnSent(xmlMessage);
|
||||
if (callback != null) callback(this, xmlMessage);
|
||||
});
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
|
||||
this.Transport.Send(message);
|
||||
this.Raise_OnSent(xmlMessage);
|
||||
if (callback != null) callback(this, xmlMessage);
|
||||
}
|
||||
}
|
||||
catch (RendezvousException ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Fatal(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
public static class Source
|
||||
{
|
||||
|
||||
public const string S10001 = "SendRequest Timeout: SendReply 메시지를 지정된 시간내에 전송하지 못하였습니다";
|
||||
|
||||
public const string S10002 = "SendReply Timeout: SendReply 메시지를 지정된 시간내에 수신하지 못하였습니다";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
333
JWH/TIB/XmlData.cs
Normal file
333
JWH/TIB/XmlData.cs
Normal file
@@ -0,0 +1,333 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using JWH;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
public class XmlData
|
||||
{
|
||||
|
||||
#region [ Variable ] ==================================================
|
||||
|
||||
private XmlDocument Document { get; set; } = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
public bool SendRequestFlag { get; set; } = false;
|
||||
|
||||
public XmlNode Message { get; set; } = null;
|
||||
|
||||
public XmlNode Header { get; set; } = null;
|
||||
|
||||
public XmlNode Body { get; set; } = null;
|
||||
|
||||
|
||||
#region [ Header Items ] -----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Header.MessageName
|
||||
/// </summary>
|
||||
public string MessageName
|
||||
{
|
||||
get { return this.GetValue("MessageName"); }
|
||||
set { this.SetValue("MessageName", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Header.TransationID
|
||||
/// </summary>
|
||||
public string TransactionID
|
||||
{
|
||||
get { return this.GetValue("TransactionID"); }
|
||||
set { this.SetValue("TransactionID", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Header.SendSubjectName
|
||||
/// </summary>
|
||||
public string SendSubjectName
|
||||
{
|
||||
get { return this.GetValue("SendSubjectName"); }
|
||||
set { this.SetValue("SendSubjectName", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Header.ReplySubjectName
|
||||
/// </summary>
|
||||
public string ReplySubjectName
|
||||
{
|
||||
get { return this.GetValue("ReplySubjectName"); }
|
||||
set { this.SetValue("ReplySubjectName", value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Body Items ] -------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Body.SITEID
|
||||
/// </summary>
|
||||
public string SITEID
|
||||
{
|
||||
get { return this.GetValue("SITEID"); }
|
||||
set { this.SetValue("SITEID", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Body.EquipmentID
|
||||
/// </summary>
|
||||
public string EquipmentID
|
||||
{
|
||||
get { return this.GetValue("EquipmentID"); }
|
||||
set { this.SetValue("EquipmentID", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Body.DateTime
|
||||
/// </summary>
|
||||
public string DateTime
|
||||
{
|
||||
get { return this.GetValue("DateTime"); }
|
||||
set { this.SetValue("DateTime", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Body.ControlMode
|
||||
/// </summary>
|
||||
public string ControlMode
|
||||
{
|
||||
get { return this.GetValue("ControlMode"); }
|
||||
set { this.SetValue("ControlMode", value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Return Items ] -----------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Return.ReturnCode
|
||||
/// </summary>
|
||||
public string ReturnCode
|
||||
{
|
||||
get { return this.GetValue("ReturnCode"); }
|
||||
set { this.SetValue("ReturnCode", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return.ReturnMessage
|
||||
/// </summary>
|
||||
public string ReturnMessage
|
||||
{
|
||||
get { return this.GetValue("ReturnMessage"); }
|
||||
set { this.SetValue("ReturnMessage", value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructor ] ===============================================
|
||||
|
||||
public XmlData()
|
||||
{
|
||||
if (this.Document == null) this.Document = new XmlDocument();
|
||||
XmlDocument document = this.Document;
|
||||
XmlNode node = null;
|
||||
|
||||
this.Message = document.CreateNode("element", "message", "");
|
||||
document.AppendChild(this.Message);
|
||||
|
||||
this.Header = document.CreateNode("element", "header", "");
|
||||
this.Message.AppendChild(this.Header);
|
||||
node = document.CreateNode("element", "messagename", ""); this.Header.AppendChild(node);
|
||||
node = document.CreateNode("element", "transactionid", ""); this.Header.AppendChild(node);
|
||||
node.InnerXml = Guid.NewGuid().ToString();
|
||||
node = document.CreateNode("element", "sendSubjectName", ""); this.Header.AppendChild(node);
|
||||
node = document.CreateNode("element", "replySubjectName", ""); this.Header.AppendChild(node);
|
||||
|
||||
this.Body = document.CreateNode("element", "body", "");
|
||||
this.Message.AppendChild(this.Body);
|
||||
node = document.CreateNode("element", "SITEID", ""); this.Body.AppendChild(node);
|
||||
node = document.CreateNode("element", "EQUIPMENTID", ""); this.Body.AppendChild(node);
|
||||
node = document.CreateNode("element", "DATETIME", ""); this.Body.AppendChild(node);
|
||||
node.InnerXml = System.DateTime.Now.ToString("yyyyMMddHHmmss");
|
||||
node = document.CreateNode("element", "CONTROLMODE", ""); this.Body.AppendChild(node);
|
||||
}
|
||||
|
||||
public XmlData(string xmlData)
|
||||
{
|
||||
this.FromString(xmlData);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.MessageName} - {this.TransactionID}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Public Method ] =============================================
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ====================================================
|
||||
|
||||
/// <summary>
|
||||
/// FromString
|
||||
/// </summary>
|
||||
/// <param name="xmlData"></param>
|
||||
public void FromString(string xmlData)
|
||||
{
|
||||
XmlDocument document = new XmlDocument();
|
||||
this.Document = document;
|
||||
if (string.IsNullOrEmpty(xmlData)) return;
|
||||
|
||||
document.LoadXml(xmlData.XMLUnescape());
|
||||
this.Message = document.GetSingleNodeByName("Message");
|
||||
this.Header = document.GetSingleNodeByName("Header");
|
||||
this.Body = document.GetSingleNodeByName("Body");
|
||||
|
||||
XmlNode msgName = this.Header.GetSingleNodeByName("MessageName");
|
||||
if (msgName.GetText().ToUpper().EndsWith("REQUEST")) this.SendRequestFlag = true;
|
||||
else this.SendRequestFlag = false;
|
||||
|
||||
// SendRequest 파일에 정의된 속성값을 읽고, 메모리에서는 제거한다.
|
||||
XmlNode msgNode = this.Document.GetSingleNodeByName("Message");
|
||||
XmlAttribute attSendRequestFlag = msgNode.GetAttribute("SendRequestFlag");
|
||||
if (attSendRequestFlag != null)
|
||||
{
|
||||
bool isSendRequestFlag = this.SendRequestFlag;
|
||||
if (bool.TryParse(attSendRequestFlag.Value, out isSendRequestFlag)) this.SendRequestFlag = isSendRequestFlag;
|
||||
msgNode.Attributes.Remove(attSendRequestFlag);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Public Method ] =============================================
|
||||
|
||||
public string GetText()
|
||||
{
|
||||
return this.Document?.GetBeautify(4, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 노드의 값을 반환한다
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public string GetValue(string name)
|
||||
{
|
||||
if (this.Document == null) return string.Empty;
|
||||
|
||||
return this.Document.GetSingleNodeByName(name)?.InnerXml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 노드의 값을 변경한다
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public XmlNode SetValue(string name, string value)
|
||||
{
|
||||
XmlNode node = this.GetNode(name);
|
||||
if (node == null) return null;
|
||||
|
||||
node.InnerXml = value;
|
||||
return node;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 노드를 반환한다
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public XmlNode GetNode(string name)
|
||||
{
|
||||
if (this.Document == null) return null;
|
||||
XmlNode node = this.Document.GetSingleNodeByName(name);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 노드들을 반환한다
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public XmlNode[] GetNodes(string name)
|
||||
{
|
||||
if (this.Document == null) return null;
|
||||
XmlNode[] nodes = this.Document.GetNodesByName(name);
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 참조된 노드의 하위에 노드를 추가한다
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public XmlNode AddChildNode(XmlNode node, string name, string value = "")
|
||||
{
|
||||
XmlNode newNode = this.Document.CreateNode("element", name, "");
|
||||
if (!string.IsNullOrEmpty(value)) newNode.InnerXml = value;
|
||||
node.AppendChild(newNode);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 참조된 노드의 앞에 노드를 추가한다
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public XmlNode InsertBefore(XmlNode node, string name, string value = "")
|
||||
{
|
||||
XmlNode newNode = this.Document.CreateNode("element", name, "");
|
||||
if (!string.IsNullOrEmpty(value)) newNode.InnerXml = value;
|
||||
this.Document.InsertBefore(newNode, node);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 참조된 노드의 뒤에 노드를 추가한다
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public XmlNode InsertAfter(XmlNode node, string name, string value = "")
|
||||
{
|
||||
XmlNode newNode = this.Document.CreateNode("element", name, "");
|
||||
if (!string.IsNullOrEmpty(value)) newNode.InnerXml = value;
|
||||
this.Document.InsertAfter(newNode, node);
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// return 노드를 반환한다
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public XmlNode GetReturn()
|
||||
{
|
||||
XmlNode node = this.GetNode("return");
|
||||
if (node != null) return node;
|
||||
|
||||
return InsertAfter(this.Body, "return");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
255
JWH/TIB/XmlMessage.cs
Normal file
255
JWH/TIB/XmlMessage.cs
Normal file
@@ -0,0 +1,255 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using JWH;
|
||||
using TIBCO.Rendezvous;
|
||||
|
||||
namespace JWH.TIB
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Message & XmlData를 관리
|
||||
/// </summary>
|
||||
public class XmlMessage : IDisposable
|
||||
{
|
||||
|
||||
#region [ Event ] =====================================================
|
||||
|
||||
public event EventHandler OnTimeOver;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Variable ] ==================================================
|
||||
|
||||
public Timer SendReplyTimer { get; protected set; } = null;
|
||||
|
||||
private Message m_Message = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Properties ] ================================================
|
||||
|
||||
/// <summary>
|
||||
/// 수신된 RequestMessage
|
||||
/// </summary>
|
||||
public XmlMessage RequestMessage { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Message
|
||||
/// </summary>
|
||||
public Message Message { get { return GetMessage(); } }
|
||||
|
||||
/// <summary>
|
||||
/// SendRequestFlag
|
||||
/// </summary>
|
||||
public bool SendRequestFlag { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// IsReply
|
||||
/// </summary>
|
||||
public bool IsReply { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// XmlData
|
||||
/// </summary>
|
||||
public XmlData XmlData { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Message.SendSubject (!=XmlData.SendSubjectName)
|
||||
/// </summary>
|
||||
public string SendSubject { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Message.ReplySubject (!=XmlData.ReplySubjectName)
|
||||
/// </summary>
|
||||
public string ReplySubject { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Rendezvous.Message.Fields
|
||||
/// </summary>
|
||||
public Dictionary<string, object> Fields { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Constructor ] ===============================================
|
||||
|
||||
/// <summary>
|
||||
/// XmlMessage
|
||||
/// </summary>
|
||||
public XmlMessage()
|
||||
{
|
||||
this.XmlData = new XmlData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메시지 파일을 기준으로 생성
|
||||
/// </summary>
|
||||
/// <param name="xmlData"></param>
|
||||
public XmlMessage(string xmlData)
|
||||
{
|
||||
this.XmlData = new XmlData(xmlData);
|
||||
this.SendRequestFlag = this.XmlData.SendRequestFlag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TIBCO.Message 정보를 기준으로 생성
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public XmlMessage(Message message)
|
||||
{
|
||||
this.m_Message = message;
|
||||
|
||||
for (uint i = 0; i < message.FieldCount; i++)
|
||||
{
|
||||
MessageField field = message.GetFieldByIndex(i);
|
||||
|
||||
switch (field.Name.ToUpper())
|
||||
{
|
||||
case "XMLDATA":
|
||||
if (field.Value != null && field.Value.GetType() == typeof(string)) this.XmlData = new XmlData(field.Value.ToString());
|
||||
break;
|
||||
case "SENDREQUESTFLAG":
|
||||
if (field.Value != null && field.Value.GetType() == typeof(bool)) this.SendRequestFlag = (bool)Convert.ChangeType(field.Value, typeof(bool));
|
||||
break;
|
||||
default:
|
||||
this.Fields.Add(field.Name, field.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.SendSubject = message.SendSubject;
|
||||
this.ReplySubject = message.ReplySubject;
|
||||
}
|
||||
|
||||
~XmlMessage()
|
||||
{
|
||||
XLogger.Instance.Debug($"{this.XmlData?.MessageName} {this.XmlData?.TransactionID}");
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.SendReplyTimer != null)
|
||||
{
|
||||
this.SendReplyTimer.Dispose();
|
||||
this.SendReplyTimer = null;
|
||||
}
|
||||
|
||||
if (this.RequestMessage != null)
|
||||
{
|
||||
this.RequestMessage.Dispose();
|
||||
this.RequestMessage = null;
|
||||
}
|
||||
|
||||
if (this.m_Message != null)
|
||||
{
|
||||
XLogger.Instance.Debug($"{m_Message}");
|
||||
this.m_Message.Dispose();
|
||||
this.m_Message = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
XLogger.Instance.Fatal(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.XmlData?.ToString()}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Raise_Events ] ==============================================
|
||||
|
||||
private void Raise_OnTimeOut()
|
||||
{
|
||||
this.OnTimeOver?.Invoke(this, new EventArgs());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Public Method ] =============================================
|
||||
|
||||
public void SetRequstMessage(XmlMessage xmlRequest)
|
||||
{
|
||||
this.RequestMessage = xmlRequest;
|
||||
this.IsReply = true;
|
||||
this.SendSubject = xmlRequest.XmlData.ReplySubjectName;
|
||||
this.ReplySubject = xmlRequest.ReplySubject;
|
||||
//if (!string.IsNullOrEmpty(xmlRequest.ReplySubject)) this.SendSubject = xmlRequest.ReplySubject;
|
||||
|
||||
this.XmlData.TransactionID = xmlRequest.XmlData.TransactionID;
|
||||
this.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName;
|
||||
this.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SendReply Timeout 체크를 시작한다
|
||||
/// </summary>
|
||||
/// <param name="interval"></param>
|
||||
public void TimerStart(int interval = 30)
|
||||
{
|
||||
interval = interval * 1000;
|
||||
this.SendReplyTimer = new Timer(this.SendReplyTimer_TimeOut, null, interval, Timeout.Infinite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SendReply Timeout 체크를 중지한다
|
||||
/// </summary>
|
||||
public void TimerStop()
|
||||
{
|
||||
if (this.SendReplyTimer != null)
|
||||
{
|
||||
this.SendReplyTimer.Dispose();
|
||||
this.SendReplyTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SendReply Timeout
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
private void SendReplyTimer_TimeOut(object state)
|
||||
{
|
||||
this.SendReplyTimer.Dispose();
|
||||
this.SendReplyTimer = null;
|
||||
this.Raise_OnTimeOut();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region [ Method ] ====================================================
|
||||
|
||||
/// <summary>
|
||||
/// 현 객체의 정보를 TIBCO.Message로 반환한다
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Message GetMessage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.m_Message != null) return this.m_Message;
|
||||
|
||||
Message message = new Message();
|
||||
if (!string.IsNullOrEmpty(this.SendSubject)) message.SendSubject = this.SendSubject;
|
||||
if (!string.IsNullOrEmpty(this.ReplySubject)) message.ReplySubject = this.ReplySubject;
|
||||
message.AddField("xmlData", this.XmlData.GetText());
|
||||
message.AddField("SendRequestFlag", this.SendRequestFlag);
|
||||
|
||||
return message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
10
JWH/TIBCO.Rendezvous.dll.config
Normal file
10
JWH/TIBCO.Rendezvous.dll.config
Normal file
@@ -0,0 +1,10 @@
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="TIBCO.Rendezvous" publicKeyToken="1a696d1f90f6158a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.0.5155.23393" newVersion="1.0.5155.23393" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
BIN
JWH/TIBCO.Rendezvous.netmodule
Normal file
BIN
JWH/TIBCO.Rendezvous.netmodule
Normal file
Binary file not shown.
109
JWH/log4net.config
Normal file
109
JWH/log4net.config
Normal file
@@ -0,0 +1,109 @@
|
||||
<log4net>
|
||||
<root>
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="file" />
|
||||
<!--<appender-ref ref="console" />-->
|
||||
<!--<appender-ref ref="database" />-->
|
||||
</root>
|
||||
|
||||
<appender name="console" type="log4net.Appender.ConsoleAppender">
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="[%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff} %level] %logger %X{id} : %X{class}.%X{method}() %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="file" type="log4net.Appender.RollingFileAppender">
|
||||
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
|
||||
<appendToFile value="true" />
|
||||
<preserveLogFileNameExtension value="true"/>
|
||||
|
||||
<rollingStyle value="Composite" />
|
||||
<file type="log4net.Util.PatternString" value="Logs/" />
|
||||
<datePattern value="yyyyMMdd'.log'" />
|
||||
<maxSizeRollBackups value="100" />
|
||||
<maximumFileSize value="30MB" />
|
||||
<staticLogFileName value="false" />
|
||||
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="[%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff} %level] %logger %X{id} : %X{class}.%X{method}() %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="database" type="log4net.Appender.AdoNetAppender">
|
||||
<bufferSize value="1" />
|
||||
<ReconnectOnError value="true" />
|
||||
<connectionType value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />
|
||||
<connectionString value="datasource=127.0.0.1;port=3306;database=logdb;user=logger;password=1234!@#$;" />
|
||||
<commandType value="StoredProcedure"/>
|
||||
<commandText value="SP_InsertLog" />
|
||||
<parameter>
|
||||
<parameterName value="LogDate" />
|
||||
<dbType value="String" />
|
||||
<size value="30" />
|
||||
<layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogSystem" />
|
||||
<dbType value="String" />
|
||||
<size value="20" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%X{system}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogName" />
|
||||
<dbType value="String" />
|
||||
<size value="30" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%c" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogID" />
|
||||
<dbType value="String" />
|
||||
<size value="30" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%X{id}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogLevel" />
|
||||
<dbType value="String" />
|
||||
<size value="10" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%p" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogClass" />
|
||||
<dbType value="String" />
|
||||
<size value="100" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%X{class}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogMethod" />
|
||||
<dbType value="String" />
|
||||
<size value="50" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%X{method}" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogMessage" />
|
||||
<dbType value="String" />
|
||||
<size value="65000" />
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%m" />
|
||||
</layout>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<parameterName value="LogException" />
|
||||
<dbType value="String" />
|
||||
<size value="65000" />
|
||||
<layout type="log4net.Layout.ExceptionLayout" />
|
||||
</parameter>
|
||||
</appender>
|
||||
|
||||
</log4net>
|
||||
4
JWH/packages.config
Normal file
4
JWH/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="log4net" version="2.0.12" targetFramework="net461" />
|
||||
</packages>
|
||||
BIN
JWH/tibrv.dll
Normal file
BIN
JWH/tibrv.dll
Normal file
Binary file not shown.
BIN
JWH/tibrvcm.dll
Normal file
BIN
JWH/tibrvcm.dll
Normal file
Binary file not shown.
BIN
JWH/tibrvcmq.dll
Normal file
BIN
JWH/tibrvcmq.dll
Normal file
Binary file not shown.
BIN
JWH/tibrvft.dll
Normal file
BIN
JWH/tibrvft.dll
Normal file
Binary file not shown.
Reference in New Issue
Block a user