diff --git a/ControlAgent/ControlAgent.csproj b/ControlAgent/ControlAgent.csproj new file mode 100644 index 0000000..be1abb8 --- /dev/null +++ b/ControlAgent/ControlAgent.csproj @@ -0,0 +1,26 @@ + + + + WinExe + net10.0-windows + enable + true + enable + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/ControlAgent/Form1.Designer.cs b/ControlAgent/Form1.Designer.cs new file mode 100644 index 0000000..d2a199b --- /dev/null +++ b/ControlAgent/Form1.Designer.cs @@ -0,0 +1,66 @@ +namespace ControlAgent +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + lblPCName = new Label(); + lblMac = new Label(); + SuspendLayout(); + // + // lblPCName + // + lblPCName.Location = new Point(226, 57); + lblPCName.Name = "lblPCName"; + lblPCName.Size = new Size(219, 39); + lblPCName.TabIndex = 0; + // + // lblMac + // + lblMac.Location = new Point(226, 141); + lblMac.Name = "lblMac"; + lblMac.Size = new Size(219, 39); + lblMac.TabIndex = 1; + // + // Form1 + // + AutoScaleDimensions = new SizeF(9F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(800, 450); + Controls.Add(lblMac); + Controls.Add(lblPCName); + Name = "Form1"; + Text = "Form1"; + ResumeLayout(false); + } + + #endregion + + private Label lblPCName; + private Label lblMac; + } +} \ No newline at end of file diff --git a/ControlAgent/Form1.cs b/ControlAgent/Form1.cs new file mode 100644 index 0000000..5e220e8 --- /dev/null +++ b/ControlAgent/Form1.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Text; +using System.Windows.Forms; + +namespace ControlAgent +{ + public partial class Form1 : Form + { + private bool _isAgentRunning = true; + + public Form1() + { + InitializeComponent(); + + // 백그라운드 태스크 형태로 서버 감지 및 수신 스레드 기동 (UI 먹통 현상 방지) + Task.Run(() => StartAgentTask()); + } + + private void StartAgentTask() + { + while (_isAgentRunning) + { + try + { + using (TcpClient client = new TcpClient()) + { + var result = client.BeginConnect("192.168.219.47", 9999, null, null); + bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5)); + + if (success) + { + client.EndConnect(result); + using (NetworkStream stream = client.GetStream()) + using (System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8)) + { + // 1. 연결되자마자 MAC 주소 송신 + string myMac = GetMacAddress() + "\n"; + byte[] macBytes = Encoding.UTF8.GetBytes(myMac); + stream.Write(macBytes, 0, macBytes.Length); + stream.Flush(); + + // 2. 서버로부터 명령/데이터 대기 (ReadLine 사용으로 안정성 확보) + while (client.Connected) + { + string command = reader.ReadLine(); // 데이터가 들어올 때까지 여기서 대기 + if (string.IsNullOrEmpty(command)) break; // 연결이 끊기면 루프 탈출 + // 명령 처리 + // 에이전트 코드의 command == "STOP" 내부를 수정 + if (command == "STOP") + { + // /f 옵션(강제 종료)과 /t 0(즉시)을 추가하고 절대 경로로 실행 + System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(); + psi.FileName = "cmd.exe"; + psi.Arguments = "/c shutdown /s /f /t 0"; // /f가 강제 종료 옵션입니다. + psi.CreateNoWindow = true; + psi.UseShellExecute = false; + + System.Diagnostics.Process.Start(psi); + + _isAgentRunning = false; + break; + } + else + { + // 데이터 전송 테스트 수신 시 처리 + MessageBox.Show("서버 메시지 수신: " + command); + } + } + } + } + } + } + catch (Exception ex) + { + Console.WriteLine("에이전트 루프 오류: " + ex.Message); + } + + if (_isAgentRunning) Thread.Sleep(5000); // 5초 대기 후 재연결 + } + } + + // MAC 물리 주소 자동 추출 내부 함수 + public string GetMacAddress() + { + foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) + { + // 가상 장치 필터링 및 오프라인 장치 필터링 수행 + if (ni.NetworkInterfaceType != NetworkInterfaceType.Loopback && + ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel && + ni.OperationalStatus == OperationalStatus.Up) + { + string mac = ni.GetPhysicalAddress().ToString(); + if (!string.IsNullOrEmpty(mac)) + { + return mac; // 수집 완료 + } + } + } + return "MAC Not Found"; + } + + public string GetMyInfo() + { + string pcName = Environment.MachineName; + string mac = GetMacAddress(); + return $"{pcName}|{mac}"; + } + } +} \ No newline at end of file diff --git a/ControlAgent/Form1.resx b/ControlAgent/Form1.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ControlAgent/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ControlAgent/Program.cs b/ControlAgent/Program.cs new file mode 100644 index 0000000..fbd914f --- /dev/null +++ b/ControlAgent/Program.cs @@ -0,0 +1,17 @@ +namespace ControlAgent +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new Form1()); + } + } +} \ No newline at end of file diff --git a/ControlAgent/Properties/Resources.Designer.cs b/ControlAgent/Properties/Resources.Designer.cs new file mode 100644 index 0000000..d5904cf --- /dev/null +++ b/ControlAgent/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// 이 코드는 도구를 사용하여 생성되었습니다. +// 런타임 버전:4.0.30319.42000 +// +// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면 +// 이러한 변경 내용이 손실됩니다. +// +//------------------------------------------------------------------------------ + +namespace ControlAgent.Properties { + using System; + + + /// + /// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다. + /// + // 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder + // 클래스에서 자동으로 생성되었습니다. + // 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을 + // 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ControlAgent.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을 + /// 재정의합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다. + /// + internal static System.Drawing.Bitmap 둥근_사각형_회색 { + get { + object obj = ResourceManager.GetObject("둥근-사각형-회색", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다. + /// + internal static System.Drawing.Bitmap 둥근_사각형_회색1 { + get { + object obj = ResourceManager.GetObject("둥근-사각형-회색1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/ControlAgent/Properties/Resources.resx b/ControlAgent/Properties/Resources.resx new file mode 100644 index 0000000..ceec9ed --- /dev/null +++ b/ControlAgent/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\둥근-사각형-회색.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\둥근-사각형-회색1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/ControlAgent/Resources/둥근-사각형-회색.png b/ControlAgent/Resources/둥근-사각형-회색.png new file mode 100644 index 0000000..f4faa43 Binary files /dev/null and b/ControlAgent/Resources/둥근-사각형-회색.png differ diff --git a/ControlAgent/Resources/둥근-사각형-회색1.png b/ControlAgent/Resources/둥근-사각형-회색1.png new file mode 100644 index 0000000..a5748c2 Binary files /dev/null and b/ControlAgent/Resources/둥근-사각형-회색1.png differ diff --git a/ControlServer.slnx b/ControlServer.slnx new file mode 100644 index 0000000..59c9ac2 --- /dev/null +++ b/ControlServer.slnx @@ -0,0 +1,4 @@ + + + + diff --git a/ControlServer/ControlServer.csproj b/ControlServer/ControlServer.csproj new file mode 100644 index 0000000..9c0f4d4 --- /dev/null +++ b/ControlServer/ControlServer.csproj @@ -0,0 +1,31 @@ + + + + WinExe + net10.0-windows + enable + true + enable + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/ControlServer/Form1.Designer.cs b/ControlServer/Form1.Designer.cs new file mode 100644 index 0000000..ab6a9c9 --- /dev/null +++ b/ControlServer/Form1.Designer.cs @@ -0,0 +1,316 @@ +namespace ControlServer +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + DataGridViewCellStyle dataGridViewCellStyle1 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle8 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle2 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle3 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle4 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle5 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle6 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle7 = new DataGridViewCellStyle(); + pannGray = new Panel(); + lblTotCnt = new Label(); + lblGrayTitle = new Label(); + pannBlue = new Panel(); + lblRunningCnt = new Label(); + lblBlueTitle = new Label(); + grdTotList = new DataGridView(); + btnLog = new Button(); + btnRegister = new Button(); + btnDataUpdate = new Button(); + txtSearch = new TextBox(); + pictureBox1 = new PictureBox(); + Col0 = new DataGridViewTextBoxColumn(); + Col1 = new DataGridViewTextBoxColumn(); + Col2 = new DataGridViewTextBoxColumn(); + Col3 = new DataGridViewTextBoxColumn(); + Col4 = new DataGridViewTextBoxColumn(); + Col5 = new DataGridViewTextBoxColumn(); + Col8 = new DataGridViewTextBoxColumn(); + pannGray.SuspendLayout(); + pannBlue.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)grdTotList).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); + SuspendLayout(); + // + // pannGray + // + pannGray.Controls.Add(lblTotCnt); + pannGray.Controls.Add(lblGrayTitle); + pannGray.Location = new Point(435, 76); + pannGray.Name = "pannGray"; + pannGray.Size = new Size(190, 120); + pannGray.TabIndex = 0; + pannGray.Paint += pannGray_Paint; + // + // lblTotCnt + // + lblTotCnt.Font = new Font("휴먼둥근헤드라인", 19.8000011F, FontStyle.Regular, GraphicsUnit.Point, 129); + lblTotCnt.ForeColor = SystemColors.HighlightText; + lblTotCnt.Location = new Point(0, 56); + lblTotCnt.Name = "lblTotCnt"; + lblTotCnt.Size = new Size(190, 48); + lblTotCnt.TabIndex = 1; + lblTotCnt.Text = "0대"; + lblTotCnt.TextAlign = ContentAlignment.MiddleCenter; + // + // lblGrayTitle + // + lblGrayTitle.AutoSize = true; + lblGrayTitle.Location = new Point(33, 20); + lblGrayTitle.Name = "lblGrayTitle"; + lblGrayTitle.Size = new Size(124, 20); + lblGrayTitle.TabIndex = 0; + lblGrayTitle.Text = "현재 단말기 대수"; + lblGrayTitle.TextAlign = ContentAlignment.MiddleCenter; + // + // pannBlue + // + pannBlue.Controls.Add(lblRunningCnt); + pannBlue.Controls.Add(lblBlueTitle); + pannBlue.Location = new Point(725, 76); + pannBlue.Name = "pannBlue"; + pannBlue.Size = new Size(190, 120); + pannBlue.TabIndex = 2; + pannBlue.Paint += pannBlue_Paint; + // + // lblRunningCnt + // + lblRunningCnt.Font = new Font("휴먼둥근헤드라인", 19.8000011F, FontStyle.Regular, GraphicsUnit.Point, 129); + lblRunningCnt.ForeColor = SystemColors.HighlightText; + lblRunningCnt.Location = new Point(0, 56); + lblRunningCnt.Name = "lblRunningCnt"; + lblRunningCnt.Size = new Size(190, 48); + lblRunningCnt.TabIndex = 1; + lblRunningCnt.Text = "0대"; + lblRunningCnt.TextAlign = ContentAlignment.MiddleCenter; + // + // lblBlueTitle + // + lblBlueTitle.Location = new Point(0, 20); + lblBlueTitle.Name = "lblBlueTitle"; + lblBlueTitle.Size = new Size(190, 20); + lblBlueTitle.TabIndex = 0; + lblBlueTitle.Text = "프로그램 실행 대수"; + lblBlueTitle.TextAlign = ContentAlignment.MiddleCenter; + // + // grdTotList + // + dataGridViewCellStyle1.Alignment = DataGridViewContentAlignment.MiddleCenter; + dataGridViewCellStyle1.BackColor = SystemColors.ButtonShadow; + dataGridViewCellStyle1.Font = new Font("맑은 고딕", 9F); + dataGridViewCellStyle1.ForeColor = SystemColors.WindowText; + dataGridViewCellStyle1.SelectionBackColor = SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = DataGridViewTriState.True; + grdTotList.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1; + grdTotList.ColumnHeadersHeight = 29; + grdTotList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; + grdTotList.Columns.AddRange(new DataGridViewColumn[] { Col0, Col1, Col2, Col3, Col4, Col5, Col8 }); + dataGridViewCellStyle8.Alignment = DataGridViewContentAlignment.MiddleCenter; + dataGridViewCellStyle8.BackColor = SystemColors.Window; + dataGridViewCellStyle8.Font = new Font("맑은 고딕", 9F); + dataGridViewCellStyle8.ForeColor = SystemColors.ControlText; + dataGridViewCellStyle8.SelectionBackColor = SystemColors.Highlight; + dataGridViewCellStyle8.SelectionForeColor = SystemColors.HighlightText; + dataGridViewCellStyle8.WrapMode = DataGridViewTriState.False; + grdTotList.DefaultCellStyle = dataGridViewCellStyle8; + grdTotList.Location = new Point(159, 308); + grdTotList.Name = "grdTotList"; + grdTotList.RowHeadersWidth = 51; + grdTotList.Size = new Size(1000, 417); + grdTotList.TabIndex = 3; + grdTotList.CellMouseClick += grdTotList_CellMouseClick; + // + // btnLog + // + btnLog.Location = new Point(1009, 244); + btnLog.Name = "btnLog"; + btnLog.Size = new Size(150, 44); + btnLog.TabIndex = 4; + btnLog.Text = "제어 이력 조회"; + btnLog.UseVisualStyleBackColor = true; + btnLog.MouseClick += btnLog_MouseClick; + // + // btnRegister + // + btnRegister.Location = new Point(880, 244); + btnRegister.Name = "btnRegister"; + btnRegister.Size = new Size(123, 44); + btnRegister.TabIndex = 5; + btnRegister.Text = "단말기 등록"; + btnRegister.UseVisualStyleBackColor = true; + btnRegister.MouseClick += btnRegister_MouseClick; + // + // btnDataUpdate + // + btnDataUpdate.Location = new Point(750, 244); + btnDataUpdate.Name = "btnDataUpdate"; + btnDataUpdate.Size = new Size(123, 44); + btnDataUpdate.TabIndex = 6; + btnDataUpdate.Text = "데이터 갱신"; + btnDataUpdate.UseVisualStyleBackColor = true; + btnDataUpdate.MouseClick += btnDataUpdate_MouseClick; + // + // txtSearch + // + txtSearch.Location = new Point(159, 244); + txtSearch.Multiline = true; + txtSearch.Name = "txtSearch"; + txtSearch.Size = new Size(256, 44); + txtSearch.TabIndex = 7; + txtSearch.TextAlign = HorizontalAlignment.Center; + // + // pictureBox1 + // + pictureBox1.Image = Properties.Resources.button_search; + pictureBox1.Location = new Point(430, 244); + pictureBox1.Name = "pictureBox1"; + pictureBox1.Size = new Size(44, 44); + pictureBox1.TabIndex = 8; + pictureBox1.TabStop = false; + // + // Col0 + // + dataGridViewCellStyle2.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col0.DefaultCellStyle = dataGridViewCellStyle2; + Col0.Frozen = true; + Col0.HeaderText = "단말기명"; + Col0.MinimumWidth = 6; + Col0.Name = "Col0"; + Col0.Width = 150; + // + // Col1 + // + dataGridViewCellStyle3.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col1.DefaultCellStyle = dataGridViewCellStyle3; + Col1.Frozen = true; + Col1.HeaderText = "MAC주소"; + Col1.MinimumWidth = 6; + Col1.Name = "Col1"; + Col1.Width = 200; + // + // Col2 + // + dataGridViewCellStyle4.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col2.DefaultCellStyle = dataGridViewCellStyle4; + Col2.Frozen = true; + Col2.HeaderText = "IP"; + Col2.MinimumWidth = 6; + Col2.Name = "Col2"; + Col2.Width = 200; + // + // Col3 + // + dataGridViewCellStyle5.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col3.DefaultCellStyle = dataGridViewCellStyle5; + Col3.Frozen = true; + Col3.HeaderText = "통신설정"; + Col3.MinimumWidth = 6; + Col3.Name = "Col3"; + Col3.Width = 125; + // + // Col4 + // + dataGridViewCellStyle6.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col4.DefaultCellStyle = dataGridViewCellStyle6; + Col4.Frozen = true; + Col4.HeaderText = "프로그램"; + Col4.MinimumWidth = 6; + Col4.Name = "Col4"; + Col4.Width = 125; + // + // Col5 + // + dataGridViewCellStyle7.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col5.DefaultCellStyle = dataGridViewCellStyle7; + Col5.Frozen = true; + Col5.HeaderText = "마지막 통신 시간"; + Col5.MinimumWidth = 6; + Col5.Name = "Col5"; + Col5.Width = 200; + // + // Col8 + // + Col8.HeaderText = "포트번호"; + Col8.MinimumWidth = 6; + Col8.Name = "Col8"; + Col8.ReadOnly = true; + Col8.Visible = false; + Col8.Width = 125; + // + // Form1 + // + AutoScaleDimensions = new SizeF(9F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1357, 737); + Controls.Add(pictureBox1); + Controls.Add(txtSearch); + Controls.Add(btnDataUpdate); + Controls.Add(btnRegister); + Controls.Add(btnLog); + Controls.Add(grdTotList); + Controls.Add(pannBlue); + Controls.Add(pannGray); + Name = "Form1"; + Text = "Form1"; + pannGray.ResumeLayout(false); + pannGray.PerformLayout(); + pannBlue.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)grdTotList).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Panel pannGray; + private Panel pannBlue; + private Label lblGrayTitle; + private Label lblBlueTitle; + private Label lblTotCnt; + private Label lblRunningCnt; + private DataGridView grdTotList; + private Button btnLog; + private Button btnRegister; + private Button btnDataUpdate; + private TextBox txtSearch; + private PictureBox pictureBox1; + private DataGridViewTextBoxColumn Col0; + private DataGridViewTextBoxColumn Col1; + private DataGridViewTextBoxColumn Col2; + private DataGridViewTextBoxColumn Col3; + private DataGridViewTextBoxColumn Col4; + private DataGridViewTextBoxColumn Col5; + private DataGridViewTextBoxColumn Col8; + } +} diff --git a/ControlServer/Form1.cs b/ControlServer/Form1.cs new file mode 100644 index 0000000..32c144f --- /dev/null +++ b/ControlServer/Form1.cs @@ -0,0 +1,503 @@ +using System.Drawing.Drawing2D; +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace ControlServer +{ + public partial class Form1 : Form + { + private List terminalList = new List(); // 리스트 생성 + private Dictionary _connectedAgents = new Dictionary(); + private TcpListener _listener; + private bool _isRunning = false; + private string _connectedIP = ""; + private System.Windows.Forms.Timer _statusTimer; + private System.Windows.Forms.Timer _dataSyncTimer; + + public Form1() + { + InitializeComponent(); + this.Load += Form1_Load; + pannGray.BackColor = Color.Transparent; // 배경색 초기화 + pannBlue.BackColor = Color.Transparent; // 배경색 초기화 + + grdTotList.RowHeadersVisible = false; // 그리드 자동으로 생성되는 첫 번째 열 제거 + grdTotList.AllowUserToAddRows = false; // 새 행 입력용 기본 로우 제거 + grdTotList.EnableHeadersVisualStyles = false; // 헤더 기본 테마 사용 안 함 + grdTotList.ColumnHeadersDefaultCellStyle.BackColor = Color.LightGray; // 헤더 배경색 + grdTotList.ColumnHeadersHeight = 40; // 헤더 높이 + grdTotList.AllowUserToResizeRows = false; // 행 높이 조절 금지 + grdTotList.AllowUserToResizeColumns = false; // 열 너비 조절 금지 + grdTotList.ReadOnly = true; // 읽기 전용 + grdTotList.ClearSelection(); + + txtSearch.PlaceholderText = "검색(단말기명, IP)"; + } + + // 가짜 데이터 로드용 함수 (테스트용 예시이며 필요 시 구현체 연결) + private void LoadSavedTerminals() + { + lblTotCnt.Text = grdTotList.RowCount.ToString() + "대"; + } + + // 폼이 화면에 나타날 때 서버를 별도의 통로(Task)로 실행 + private void Form1_Load(object sender, EventArgs e) + { + LoadSavedTerminals(); // 기존에 저장된 단말기 데이터 리스트 로드 + InitStatusTimer(); // 에이전트pc 상태 여부 확인 + + if (grdTotList.Rows.Count > 0) + { + // 등록된 단말기가 있다면 상태 체크 스레드 및 서버 리스너 시작 + _ = Task.Run(() => StartServer()); + _ = Task.Run(() => CheckAllAlliveStatus()); // 상시 또는 최초 상태 체크 + } + else + { + // 등록된 단말기가 하나도 없다면 리스너를 구동하지 않음 + MessageBox.Show("등록된 단말기가 없어 서버를 대기 상태로 유지합니다. 단말기를 등록해주세요."); + } + } + private void InitStatusTimer() + { + _statusTimer = new System.Windows.Forms.Timer(); + _statusTimer.Interval = 5000; // 5초마다 체크 + _statusTimer.Tick += (s, e) => { + CheckAllAlliveStatus(); + }; + _statusTimer.Start(); + } + + // 기존 등록된 단말기들의 현재 On/Off 상태를 체크하는 함수 + private void CheckAllAlliveStatus() + { + foreach (DataGridViewRow row in grdTotList.Rows) + { + if (row.IsNewRow) continue; + string ip = row.Cells[2].Value?.ToString(); + if (string.IsNullOrEmpty(ip)) continue; + + // 현재 서버에 소켓이 활성화되어 연결되어 있는지 확인 + bool isAlive = false; + lock (_connectedAgents) + { + if (_connectedAgents.ContainsKey(ip)) + { + TcpClient client = _connectedAgents[ip]; + // 소켓이 연결되어 있고, 실제 연결 상태가 양호한지 체크 + if (client != null && client.Connected) + { + isAlive = true; + } + } + } + + // 만약 소켓이 연결 안 되어 있다면 보조 수단으로 원래의 PingTest를 수행해볼 수 있음 + if (!isAlive) + { + isAlive = PingTest(ip); + } + + this.Invoke(new Action(() => { + if (isAlive) + { + row.Cells[4].Value = "Start"; + row.Cells[4].Style.BackColor = Color.Green; + row.Cells[4].Style.ForeColor = Color.White; + } + else + { + row.Cells[4].Value = "Stop"; + row.Cells[4].Style.BackColor = Color.Red; + row.Cells[4].Style.ForeColor = Color.White; + } + row.Cells[4].Style.Alignment = DataGridViewContentAlignment.MiddleCenter; + })); + } + this.Invoke(new Action(() => UpdateRunningCount())); + } + + private bool PingTest(string ip) + { + if (string.IsNullOrEmpty(ip)) return false; + try + { + using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping()) + { + var reply = ping.Send(ip, 1000); // 1초 타임아웃 + return reply.Status == System.Net.NetworkInformation.IPStatus.Success; + } + } + catch { return false; } + } + + // 서버 시작 함수 + private async Task StartServer() + { + try + { + if (_isRunning) return; // 이미 실행 중이면 중복 방지 + + _listener = new TcpListener(IPAddress.Any, 9999); + _listener.Start(); + MessageBox.Show("서버 연결 중..."); + _isRunning = true; + + while (_isRunning) + { + // 에이전트의 접속을 비동기로 대기 + TcpClient client = await _listener.AcceptTcpClientAsync(); + + // 에이전트 접속 처리 핸들러 실행 + _ = Task.Run(() => HandleAgent(client)); + } + } + catch (Exception ex) + { + // 리스너가 중단되었을 때의 예외 처리 제외 처리 + if (_isRunning) + { + MessageBox.Show("서버 구동 오류: " + ex.Message); + } + } + } + + // 에이전트에서 데이터 받기 + private void HandleAgent(TcpClient client) + { + try + { + string clientIP = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString(); + + // using을 쓰지 않고 직접 스트림과 리더를 생성(함수가 끝나도 닫히지 않게) + NetworkStream stream = client.GetStream(); + System.IO.StreamReader reader = new System.IO.StreamReader(stream, Encoding.UTF8); + + // 에이전트가 보낸 첫 줄(MAC 주소) + string receivedMac = reader.ReadLine(); + + if (!string.IsNullOrEmpty(receivedMac)) + { + this.Invoke(new Action(() => { + // 기존 연결이 있다면 안전하게 닫고 교체 + if (_connectedAgents.ContainsKey(clientIP)) + { + try { _connectedAgents[clientIP].Close(); } catch { } + } + + _connectedAgents[clientIP] = client; // 소켓 유지 + UpdateAgentStatusByMac(receivedMac, clientIP); + })); + + // 서버 소켓이 닫히거나 에이전트가 끊어질 때까지 + // 이 스레드가 종료되지 않고 백그라운드에서 계속 대기하도록 루프를 돌려줌 + // (에이전트로부터 추가적인 메시지를 받을 때도 여기서 처리 가능) + while (client.Connected) + { + // 에이전트가 보낸 데이터가 없다면 여기서 대기 + // 에이전트가 연결을 끊으면 null이 들어와 루프를 빠져나감 + string agentMsg = reader.ReadLine(); + if (agentMsg == null) break; + } + } + } + catch (Exception ex) + { + Console.WriteLine("서버 핸들러 오류: " + ex.Message); + } + finally + { + // 연결이 최종적으로 끊기면 딕셔너리에서 제거 및 리소스 정리 + try + { + string clientIP = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString(); + lock (_connectedAgents) + { + if (_connectedAgents.ContainsKey(clientIP)) + { + _connectedAgents.Remove(clientIP); + } + } + } + catch { } + client.Close(); + } + } + + // MAC 주소를 기반으로 에이전트 매칭 및 상태 업데이트 + private void UpdateAgentStatusByMac(string clientMac, string clientIP) + { + // 수신된 MAC에서 불필요한 문자 제거 + string cleanClientMac = clientMac.Replace("-", "").Replace(":", "").Replace(" ", "").ToUpper().Trim(); + + bool isMatched = false; + + this.Invoke(new Action(() => { + foreach (DataGridViewRow row in grdTotList.Rows) + { + string gridIp = row.Cells[2].Value.ToString(); + + if (gridIp == clientIP) + { + row.Cells[1].Value = cleanClientMac; + row.Cells[4].Value = "Start"; + row.Cells[4].Style.BackColor = Color.Green; + row.Cells[4].Style.ForeColor = Color.White; + row.Cells[5].Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + + isMatched = true; + break; + } + } + + if (!isMatched) + { + Console.WriteLine($"매칭 실패! 수신된 MAC: {cleanClientMac}"); + } + + UpdateRunningCount(); + })); + } + + // 상단의 프로그램 실행 대수 갱신용 공통 메서드 + private void UpdateRunningCount() + { + int startCount = 0; + foreach (DataGridViewRow row in grdTotList.Rows) + { + if (row.IsNewRow) continue; + if (row.Cells[4].Value?.ToString() == "Start") + { + startCount++; + } + } + lblRunningCnt.Text = startCount.ToString() + "대"; + } + + private void btnRegister_MouseClick(object sender, MouseEventArgs e) + { + // 단말기 등록 팝업 호출 + Form2 form = new Form2(); + + if (form.ShowDialog() == DialogResult.OK) + { + TerminalInfo data = form.TerminalData; + + grdTotList.Rows.Add( + data.TerminalName, // 단말기명 + data.Mac, // MAC 주소 + data.IP, // IP + "설정", // 통신설정 버튼 + "Stop", // 기본 상태 + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), + data.Port // 포트번호 + ); + + int rowIndex = grdTotList.Rows.Count - 1; + + // 프로그램 열 스타일 지정 + DataGridViewCell cell4 = grdTotList.Rows[rowIndex].Cells[4]; + cell4.Style.BackColor = Color.Red; + cell4.Style.ForeColor = Color.White; + cell4.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; + + // 통신설정 열 스타일 지정 + DataGridViewCell cell3 = grdTotList.Rows[rowIndex].Cells[3]; + cell3.Style.BackColor = Color.LightGray; + cell3.Style.ForeColor = Color.Black; + cell3.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; + + // 현재 단말기 개수 업데이트 + lblTotCnt.Text = grdTotList.RowCount.ToString() + "대"; + + // 단말 등록 완료 후 리스너가 구동 중이 아니었다면 리스너 최초 구동 개시 + if (!_isRunning) + { + _ = Task.Run(() => StartServer()); + } + + // 기접속된 IP가 있는 장치라면 바로 연동 매칭 + if (!string.IsNullOrEmpty(_connectedIP) && _connectedIP == data.IP) + { + UpdateAgentStatusByMac(data.Mac, data.IP); + } + } + } + + private void btnDataUpdate_MouseClick(object sender, MouseEventArgs e) + { + // 1. 메시지 전송 + SendDataToAllAgents("데이터 전송 테스트(수동)"); + + // 2. 기존 로직 + Popup popup = new Popup("전체 단말기에 데이터 전송을 시도했습니다."); + popup.ShowDialog(); + CheckAllAlliveStatus(); + } + + private void btnLog_MouseClick(object sender, MouseEventArgs e) + { + Form4 form = new Form4(); + form.Show(); + } + + private void grdTotList_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) + { + grdTotList.ClearSelection(); + + // 헤더 클릭 방지 + if (e.RowIndex < 0) return; + + // 통신설정 버튼 열 클릭 시 + if (e.ColumnIndex == 3) + { + var row = grdTotList.Rows[e.RowIndex]; + string TerminalName = row.Cells[0].Value?.ToString() ?? ""; + string TerminalIp = row.Cells[2].Value?.ToString() ?? ""; + + Form3 form = new Form3(TerminalName, TerminalIp); + form.ShowDialog(); + } + // 프로그램 작동 제어 제어 열 클릭 시 + else if (e.ColumnIndex == 4) + { + DataGridViewRow row = grdTotList.Rows[e.RowIndex]; + DataGridViewCell cell4 = row.Cells[4]; + + string status = cell4.Value?.ToString() ?? ""; + string targetIP = row.Cells[2].Value?.ToString() ?? ""; + string targetMac = row.Cells[1].Value?.ToString() ?? ""; + + if (status == "Start") + { + // 에이전트 PC로 원격 강제 종료 패킷 전달 + SendStopCommandToAgent(targetIP); + + cell4.Value = "Stop"; + cell4.Style.BackColor = Color.Red; + cell4.Style.ForeColor = Color.White; + } + else + { + // WOL 매직 패킷 송신 + if (!string.IsNullOrEmpty(targetMac)) + { + SendWakeOnLan(targetMac); + + cell4.Value = "Start"; + cell4.Style.BackColor = Color.Green; + cell4.Style.ForeColor = Color.White; + } + else + { + MessageBox.Show("등록된 MAC 주소가 없습니다."); + } + } + + cell4.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; + UpdateRunningCount(); + } + } + + // [원격 끄기 구현] 소켓 스트림 연동을 위한 에이전트 대상 종료 전송 함수 + private void SendStopCommandToAgent(string ip) + { + try + { + if (_connectedAgents.ContainsKey(ip)) + { + TcpClient client = _connectedAgents[ip]; + if (client.Connected) + { + // 중요: 뒤에 "\n"을 추가하여 에이전트의 ReadLine()이 끝을 인식하게 합니다. + byte[] msg = Encoding.UTF8.GetBytes("STOP\n"); + client.GetStream().Write(msg, 0, msg.Length); + client.GetStream().Flush(); + } + } + else + { + MessageBox.Show("에이전트가 서버에 연결되어 있지 않습니다."); + } + } + catch (Exception ex) + { + MessageBox.Show("종료 명령 전송 실패: " + ex.Message); + } + } + + // WOL 매직 패킷 전송 함수 + private void SendWakeOnLan(string macAddress) + { + try + { + string cleanMac = macAddress.Replace("-", "").Replace(":", "").Replace(" ", "").Trim(); + + if (cleanMac.Length != 12) + { + MessageBox.Show("올바른 MAC 주소 형식이 아닙니다."); + return; + } + + byte[] bytes = new byte[102]; + + for (int i = 0; i < 6; i++) + { + bytes[i] = 0xFF; + } + + byte[] macBytes = new byte[6]; + for (int i = 0; i < 6; i++) + { + macBytes[i] = Convert.ToByte(cleanMac.Substring(i * 2, 2), 16); + } + + for (int i = 1; i <= 16; i++) + { + Array.Copy(macBytes, 0, bytes, i * 6, 6); + } + + using (UdpClient client = new UdpClient()) + { + client.Connect(IPAddress.Parse("255.255.255.255"), 9); + client.Send(bytes, bytes.Length); + } + } + catch (Exception ex) + { + MessageBox.Show("WOL 전송 실패: " + ex.Message); + } + } + + private void SendDataToAllAgents(string message) + { + // 메시지 끝에 \n을 붙여서 에이전트가 ReadLine()으로 잘 읽게함 + byte[] data = Encoding.UTF8.GetBytes(message + "\n"); + + lock (_connectedAgents) // 여러 스레드에서 접근할 수 있으므로 lock 사용 + { + foreach (var kvp in _connectedAgents) + { + try + { + TcpClient client = kvp.Value; + if (client != null && client.Connected) + { + NetworkStream stream = client.GetStream(); + stream.Write(data, 0, data.Length); + stream.Flush(); + } + } + catch (Exception ex) + { + Console.WriteLine($"전송 실패 ({kvp.Key}): {ex.Message}"); + } + } + } + } + + private void pannGray_Paint(object sender, PaintEventArgs e) { } + private void pannBlue_Paint(object sender, PaintEventArgs e) { } + } +} \ No newline at end of file diff --git a/ControlServer/Form1.resx b/ControlServer/Form1.resx new file mode 100644 index 0000000..d7de2eb --- /dev/null +++ b/ControlServer/Form1.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/ControlServer/Form2.Designer.cs b/ControlServer/Form2.Designer.cs new file mode 100644 index 0000000..51f9174 --- /dev/null +++ b/ControlServer/Form2.Designer.cs @@ -0,0 +1,151 @@ +namespace ControlServer +{ + partial class Form2 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + lbl0 = new Label(); + lbl1 = new Label(); + txtBoxName = new TextBox(); + txtBoxIP = new TextBox(); + btnRegister = new Button(); + btnCancel = new Button(); + txtBoxPort = new TextBox(); + lbl5 = new Label(); + SuspendLayout(); + // + // lbl0 + // + lbl0.BackColor = SystemColors.ControlDark; + lbl0.BorderStyle = BorderStyle.FixedSingle; + lbl0.Location = new Point(277, 106); + lbl0.Name = "lbl0"; + lbl0.Size = new Size(293, 50); + lbl0.TabIndex = 0; + lbl0.Text = "단말기명"; + lbl0.TextAlign = ContentAlignment.MiddleLeft; + // + // lbl1 + // + lbl1.BackColor = SystemColors.ControlDark; + lbl1.BorderStyle = BorderStyle.FixedSingle; + lbl1.Location = new Point(277, 156); + lbl1.Name = "lbl1"; + lbl1.Size = new Size(293, 50); + lbl1.TabIndex = 1; + lbl1.Text = "IP"; + lbl1.TextAlign = ContentAlignment.MiddleLeft; + // + // txtBoxName + // + txtBoxName.Location = new Point(572, 106); + txtBoxName.Multiline = true; + txtBoxName.Name = "txtBoxName"; + txtBoxName.Size = new Size(507, 50); + txtBoxName.TabIndex = 4; + // + // txtBoxIP + // + txtBoxIP.Location = new Point(572, 156); + txtBoxIP.Multiline = true; + txtBoxIP.Name = "txtBoxIP"; + txtBoxIP.Size = new Size(507, 50); + txtBoxIP.TabIndex = 5; + // + // btnRegister + // + btnRegister.BackColor = SystemColors.Desktop; + btnRegister.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); + btnRegister.ForeColor = SystemColors.Window; + btnRegister.Location = new Point(460, 291); + btnRegister.Name = "btnRegister"; + btnRegister.Size = new Size(174, 56); + btnRegister.TabIndex = 9; + btnRegister.Text = "등록"; + btnRegister.UseVisualStyleBackColor = false; + btnRegister.MouseClick += btnRegister_MouseClick; + // + // btnCancel + // + btnCancel.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); + btnCancel.Location = new Point(710, 291); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new Size(174, 56); + btnCancel.TabIndex = 10; + btnCancel.Text = "취소"; + btnCancel.UseVisualStyleBackColor = true; + btnCancel.MouseClick += btnCancel_MouseClick; + // + // txtBoxPort + // + txtBoxPort.Location = new Point(572, 206); + txtBoxPort.Multiline = true; + txtBoxPort.Name = "txtBoxPort"; + txtBoxPort.Size = new Size(507, 50); + txtBoxPort.TabIndex = 12; + // + // lbl5 + // + lbl5.BackColor = SystemColors.ControlDark; + lbl5.BorderStyle = BorderStyle.FixedSingle; + lbl5.Location = new Point(277, 206); + lbl5.Name = "lbl5"; + lbl5.Size = new Size(293, 50); + lbl5.TabIndex = 11; + lbl5.Text = "Port"; + lbl5.TextAlign = ContentAlignment.MiddleLeft; + // + // Form2 + // + AutoScaleDimensions = new SizeF(9F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1357, 737); + Controls.Add(txtBoxPort); + Controls.Add(lbl5); + Controls.Add(btnCancel); + Controls.Add(btnRegister); + Controls.Add(txtBoxIP); + Controls.Add(txtBoxName); + Controls.Add(lbl1); + Controls.Add(lbl0); + Name = "Form2"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Label lbl0; + private Label lbl1; + private TextBox txtBoxName; + private TextBox txtBoxIP; + private Button btnRegister; + private Button btnCancel; + private TextBox txtBoxPort; + private Label lbl5; + } +} \ No newline at end of file diff --git a/ControlServer/Form2.cs b/ControlServer/Form2.cs new file mode 100644 index 0000000..e3e82b9 --- /dev/null +++ b/ControlServer/Form2.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace ControlServer +{ + public partial class Form2 : Form + { + public TerminalInfo TerminalData { get; private set; } = new TerminalInfo(); + + public Form2() + { + InitializeComponent(); + + btnRegister.Enabled = false; // 저장버튼 비활성화 + // 모든 텍스트박스의 값이 변할 때마다 실행될 이벤트 연결 + txtBoxName.TextChanged += ValidateInputs; + txtBoxIP.TextChanged += ValidateInputs; + txtBoxPort.TextChanged += ValidateInputs; + } + + private void ValidateInputs(object? sender, EventArgs e) + { + // 모든 텍스트박스가 공백이 아닐 때만 true + bool isValid = !string.IsNullOrWhiteSpace(txtBoxName.Text) && + !string.IsNullOrWhiteSpace(txtBoxIP.Text) && + !string.IsNullOrWhiteSpace(txtBoxPort.Text); + + // 저장 버튼 활성화 상태 조절 + btnRegister.Enabled = isValid; + } + + private void btnCancel_MouseClick(object sender, MouseEventArgs e) + { + // 취소 버튼 + this.Close(); + } + + private void btnRegister_MouseClick(object sender, MouseEventArgs e) + { + // 1. DB 중복 데이터 확인 + + // 2. 중복 데이터 없을 경우 DB에 데이터 추가 + // DB 가져오면 데이터 넘겨주는게 아니라 테이블에 데이터 추가하고 Form1 화면에서 데이터 가져와 리스트 보여주는 형식으로 변경할 예정 + Popup popup = new Popup("등록되었습니다."); + + if (popup.ShowDialog() == DialogResult.OK) + { + this.TerminalData = new TerminalInfo + { + TerminalName = txtBoxName.Text.Trim(), + IP = txtBoxIP.Text.Trim(), + Port = txtBoxPort.Text.Trim() + }; + } + + this.DialogResult = DialogResult.OK; + this.Close(); + } + } +} diff --git a/ControlServer/Form2.resx b/ControlServer/Form2.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ControlServer/Form2.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ControlServer/Form3.Designer.cs b/ControlServer/Form3.Designer.cs new file mode 100644 index 0000000..aa0e3a8 --- /dev/null +++ b/ControlServer/Form3.Designer.cs @@ -0,0 +1,317 @@ +namespace ControlServer +{ + partial class Form3 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + lblTerminalName = new Label(); + lblTerminalIP = new Label(); + label1 = new Label(); + label2 = new Label(); + lbl0 = new Label(); + label3 = new Label(); + label4 = new Label(); + pannUpdate = new Panel(); + rdoUpdate5m = new RadioButton(); + rdoUpdate3m = new RadioButton(); + rdoUpdate1m = new RadioButton(); + pannStartTime = new Panel(); + label5 = new Label(); + txtBoxOnMM = new TextBox(); + txtBoxOnYY = new TextBox(); + pannStopTime = new Panel(); + label6 = new Label(); + txtBoxOffMM = new TextBox(); + txtBoxOffYY = new TextBox(); + btnCancel = new Button(); + btnUpdate = new Button(); + pannUpdate.SuspendLayout(); + pannStartTime.SuspendLayout(); + pannStopTime.SuspendLayout(); + SuspendLayout(); + // + // lblTerminalName + // + lblTerminalName.Font = new Font("맑은 고딕", 9F, FontStyle.Bold, GraphicsUnit.Point, 129); + lblTerminalName.Location = new Point(430, 42); + lblTerminalName.Name = "lblTerminalName"; + lblTerminalName.Size = new Size(288, 50); + lblTerminalName.TabIndex = 0; + lblTerminalName.TextAlign = ContentAlignment.MiddleLeft; + // + // lblTerminalIP + // + lblTerminalIP.Location = new Point(430, 118); + lblTerminalIP.Name = "lblTerminalIP"; + lblTerminalIP.Size = new Size(288, 50); + lblTerminalIP.TabIndex = 1; + lblTerminalIP.TextAlign = ContentAlignment.MiddleLeft; + // + // label1 + // + label1.Location = new Point(254, 42); + label1.Name = "label1"; + label1.Size = new Size(147, 50); + label1.TabIndex = 2; + label1.Text = "단말기명"; + label1.TextAlign = ContentAlignment.MiddleLeft; + // + // label2 + // + label2.Location = new Point(254, 118); + label2.Name = "label2"; + label2.Size = new Size(147, 50); + label2.TabIndex = 3; + label2.Text = "IP"; + label2.TextAlign = ContentAlignment.MiddleLeft; + // + // lbl0 + // + lbl0.BackColor = SystemColors.ControlDark; + lbl0.BorderStyle = BorderStyle.FixedSingle; + lbl0.Location = new Point(254, 223); + lbl0.Name = "lbl0"; + lbl0.Size = new Size(159, 50); + lbl0.TabIndex = 4; + lbl0.Text = "갱신주기"; + lbl0.TextAlign = ContentAlignment.MiddleLeft; + // + // label3 + // + label3.BackColor = SystemColors.ControlDark; + label3.BorderStyle = BorderStyle.FixedSingle; + label3.Location = new Point(254, 273); + label3.Name = "label3"; + label3.Size = new Size(159, 50); + label3.TabIndex = 5; + label3.Text = "프로그램 ON 시간"; + label3.TextAlign = ContentAlignment.MiddleLeft; + // + // label4 + // + label4.BackColor = SystemColors.ControlDark; + label4.BorderStyle = BorderStyle.FixedSingle; + label4.Location = new Point(254, 323); + label4.Name = "label4"; + label4.Size = new Size(159, 50); + label4.TabIndex = 6; + label4.Text = "프로그램 OFF 시간"; + label4.TextAlign = ContentAlignment.MiddleLeft; + // + // pannUpdate + // + pannUpdate.BorderStyle = BorderStyle.FixedSingle; + pannUpdate.Controls.Add(rdoUpdate5m); + pannUpdate.Controls.Add(rdoUpdate3m); + pannUpdate.Controls.Add(rdoUpdate1m); + pannUpdate.Location = new Point(413, 223); + pannUpdate.Name = "pannUpdate"; + pannUpdate.Size = new Size(356, 50); + pannUpdate.TabIndex = 7; + // + // rdoUpdate5m + // + rdoUpdate5m.AutoSize = true; + rdoUpdate5m.Location = new Point(157, 12); + rdoUpdate5m.Name = "rdoUpdate5m"; + rdoUpdate5m.Size = new Size(53, 24); + rdoUpdate5m.TabIndex = 2; + rdoUpdate5m.TabStop = true; + rdoUpdate5m.Text = "5분"; + rdoUpdate5m.UseVisualStyleBackColor = true; + // + // rdoUpdate3m + // + rdoUpdate3m.AutoSize = true; + rdoUpdate3m.Location = new Point(86, 12); + rdoUpdate3m.Name = "rdoUpdate3m"; + rdoUpdate3m.Size = new Size(53, 24); + rdoUpdate3m.TabIndex = 1; + rdoUpdate3m.TabStop = true; + rdoUpdate3m.Text = "3분"; + rdoUpdate3m.UseVisualStyleBackColor = true; + // + // rdoUpdate1m + // + rdoUpdate1m.AutoSize = true; + rdoUpdate1m.Location = new Point(16, 12); + rdoUpdate1m.Name = "rdoUpdate1m"; + rdoUpdate1m.Size = new Size(53, 24); + rdoUpdate1m.TabIndex = 0; + rdoUpdate1m.TabStop = true; + rdoUpdate1m.Text = "1분"; + rdoUpdate1m.UseVisualStyleBackColor = true; + // + // pannStartTime + // + pannStartTime.BorderStyle = BorderStyle.FixedSingle; + pannStartTime.Controls.Add(label5); + pannStartTime.Controls.Add(txtBoxOnMM); + pannStartTime.Controls.Add(txtBoxOnYY); + pannStartTime.Location = new Point(413, 273); + pannStartTime.Name = "pannStartTime"; + pannStartTime.Size = new Size(356, 50); + pannStartTime.TabIndex = 8; + // + // label5 + // + label5.AutoSize = true; + label5.Location = new Point(83, 14); + label5.Name = "label5"; + label5.Size = new Size(12, 20); + label5.TabIndex = 2; + label5.Text = ":"; + // + // txtBoxOnMM + // + txtBoxOnMM.Location = new Point(99, 11); + txtBoxOnMM.Name = "txtBoxOnMM"; + txtBoxOnMM.Size = new Size(64, 27); + txtBoxOnMM.TabIndex = 1; + txtBoxOnMM.TextAlign = HorizontalAlignment.Center; + // + // txtBoxOnYY + // + txtBoxOnYY.Location = new Point(16, 11); + txtBoxOnYY.Name = "txtBoxOnYY"; + txtBoxOnYY.Size = new Size(64, 27); + txtBoxOnYY.TabIndex = 0; + txtBoxOnYY.TextAlign = HorizontalAlignment.Center; + // + // pannStopTime + // + pannStopTime.BorderStyle = BorderStyle.FixedSingle; + pannStopTime.Controls.Add(label6); + pannStopTime.Controls.Add(txtBoxOffMM); + pannStopTime.Controls.Add(txtBoxOffYY); + pannStopTime.Location = new Point(413, 323); + pannStopTime.Name = "pannStopTime"; + pannStopTime.Size = new Size(356, 50); + pannStopTime.TabIndex = 9; + // + // label6 + // + label6.AutoSize = true; + label6.Location = new Point(83, 14); + label6.Name = "label6"; + label6.Size = new Size(12, 20); + label6.TabIndex = 5; + label6.Text = ":"; + // + // txtBoxOffMM + // + txtBoxOffMM.Location = new Point(99, 11); + txtBoxOffMM.Name = "txtBoxOffMM"; + txtBoxOffMM.Size = new Size(64, 27); + txtBoxOffMM.TabIndex = 4; + txtBoxOffMM.TextAlign = HorizontalAlignment.Center; + // + // txtBoxOffYY + // + txtBoxOffYY.Location = new Point(16, 11); + txtBoxOffYY.Name = "txtBoxOffYY"; + txtBoxOffYY.Size = new Size(64, 27); + txtBoxOffYY.TabIndex = 3; + txtBoxOffYY.TextAlign = HorizontalAlignment.Center; + // + // btnCancel + // + btnCancel.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); + btnCancel.Location = new Point(559, 408); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new Size(174, 56); + btnCancel.TabIndex = 12; + btnCancel.Text = "취소"; + btnCancel.UseVisualStyleBackColor = true; + btnCancel.MouseClick += btnCancel_MouseClick; + // + // btnUpdate + // + btnUpdate.BackColor = SystemColors.Desktop; + btnUpdate.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); + btnUpdate.ForeColor = SystemColors.Window; + btnUpdate.Location = new Point(309, 408); + btnUpdate.Name = "btnUpdate"; + btnUpdate.Size = new Size(174, 56); + btnUpdate.TabIndex = 11; + btnUpdate.Text = "수정"; + btnUpdate.UseVisualStyleBackColor = false; + btnUpdate.MouseClick += btnUpdate_MouseClick; + // + // Form3 + // + AutoScaleDimensions = new SizeF(9F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1008, 563); + Controls.Add(btnCancel); + Controls.Add(btnUpdate); + Controls.Add(pannStopTime); + Controls.Add(pannStartTime); + Controls.Add(pannUpdate); + Controls.Add(label4); + Controls.Add(label3); + Controls.Add(lbl0); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(lblTerminalIP); + Controls.Add(lblTerminalName); + Name = "Form3"; + Text = "Form3"; + pannUpdate.ResumeLayout(false); + pannUpdate.PerformLayout(); + pannStartTime.ResumeLayout(false); + pannStartTime.PerformLayout(); + pannStopTime.ResumeLayout(false); + pannStopTime.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private Label lblTerminalName; + private Label lblTerminalIP; + private Label label1; + private Label label2; + private Label lbl0; + private Label label3; + private Label label4; + private Panel pannUpdate; + private Panel pannStartTime; + private Panel pannStopTime; + private RadioButton rdoUpdate1m; + private RadioButton rdoUpdate5m; + private RadioButton rdoUpdate3m; + private TextBox txtBoxOnYY; + private TextBox txtBoxOnMM; + private Label label5; + private Label label6; + private TextBox txtBoxOffMM; + private TextBox txtBoxOffYY; + private Button btnCancel; + private Button btnUpdate; + } +} \ No newline at end of file diff --git a/ControlServer/Form3.cs b/ControlServer/Form3.cs new file mode 100644 index 0000000..7f7b793 --- /dev/null +++ b/ControlServer/Form3.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace ControlServer +{ + public partial class Form3 : Form + { + public Form3(string terminalName, string terminalIP) // 매개변수 추가 + { + InitializeComponent(); + + // 가져온 데이터를 Form3의 라벨이나 텍스트박스에 표시 + lblTerminalName.Text = terminalName; + lblTerminalIP.Text = terminalIP; + + txtBoxOnYY.TextChanged += ValidateInputs; + txtBoxOnMM.TextChanged += ValidateInputs; + txtBoxOffYY.TextChanged += ValidateInputs; + txtBoxOffMM.TextChanged += ValidateInputs; + txtBoxOnYY.PlaceholderText = "YY"; + txtBoxOnMM.PlaceholderText = "MM"; + txtBoxOffYY.PlaceholderText = "YY"; + txtBoxOffMM.PlaceholderText = "MM"; + } + + private void ValidateInputs(object? sender, EventArgs e) + { + // 프로그램 시간 조건 체크 + bool isOnYYEmpty = string.IsNullOrWhiteSpace(txtBoxOnYY.Text); + bool isOnMMEmpty = string.IsNullOrWhiteSpace(txtBoxOnMM.Text); + bool isOffYYEmpty = string.IsNullOrWhiteSpace(txtBoxOffYY.Text); + bool isOffMMEmpty = string.IsNullOrWhiteSpace(@txtBoxOffMM.Text); + + // 둘 다 비어있거나(AND), 둘 다 비어있지 않거나(AND) + bool isTimeValid = (isOnYYEmpty && isOnMMEmpty && isOffYYEmpty && isOffMMEmpty) || (!isOnYYEmpty && !isOnMMEmpty && !isOffYYEmpty && !isOffMMEmpty); + + // 저장 버튼 활성화 + btnUpdate.Enabled = isTimeValid; + } + + private void btnCancel_MouseClick(object sender, MouseEventArgs e) + { + this.Close(); + } + + private void btnUpdate_MouseClick(object sender, MouseEventArgs e) + { + // 수정 + // 수정 시 DB 저장 + } + } +} diff --git a/ControlServer/Form3.resx b/ControlServer/Form3.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ControlServer/Form3.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ControlServer/Form4.Designer.cs b/ControlServer/Form4.Designer.cs new file mode 100644 index 0000000..674169c --- /dev/null +++ b/ControlServer/Form4.Designer.cs @@ -0,0 +1,166 @@ +namespace ControlServer +{ + partial class Form4 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + DataGridViewCellStyle dataGridViewCellStyle7 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle12 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle8 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle9 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle10 = new DataGridViewCellStyle(); + DataGridViewCellStyle dataGridViewCellStyle11 = new DataGridViewCellStyle(); + grdLog = new DataGridView(); + Col5 = new DataGridViewTextBoxColumn(); + Col0 = new DataGridViewTextBoxColumn(); + Col3 = new DataGridViewTextBoxColumn(); + Col4 = new DataGridViewTextBoxColumn(); + Col6 = new DataGridViewTextBoxColumn(); + Col7 = new DataGridViewTextBoxColumn(); + btnPrev = new Button(); + ((System.ComponentModel.ISupportInitialize)grdLog).BeginInit(); + SuspendLayout(); + // + // grdLog + // + dataGridViewCellStyle7.Alignment = DataGridViewContentAlignment.MiddleCenter; + dataGridViewCellStyle7.BackColor = SystemColors.ButtonShadow; + dataGridViewCellStyle7.Font = new Font("맑은 고딕", 9F); + dataGridViewCellStyle7.ForeColor = SystemColors.WindowText; + dataGridViewCellStyle7.SelectionBackColor = SystemColors.Highlight; + dataGridViewCellStyle7.SelectionForeColor = SystemColors.HighlightText; + dataGridViewCellStyle7.WrapMode = DataGridViewTriState.True; + grdLog.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle7; + grdLog.ColumnHeadersHeight = 29; + grdLog.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; + grdLog.Columns.AddRange(new DataGridViewColumn[] { Col5, Col0, Col3, Col4, Col6, Col7 }); + dataGridViewCellStyle12.Alignment = DataGridViewContentAlignment.MiddleCenter; + dataGridViewCellStyle12.BackColor = SystemColors.Window; + dataGridViewCellStyle12.Font = new Font("맑은 고딕", 9F); + dataGridViewCellStyle12.ForeColor = SystemColors.ControlText; + dataGridViewCellStyle12.SelectionBackColor = SystemColors.Highlight; + dataGridViewCellStyle12.SelectionForeColor = SystemColors.HighlightText; + dataGridViewCellStyle12.WrapMode = DataGridViewTriState.False; + grdLog.DefaultCellStyle = dataGridViewCellStyle12; + grdLog.Location = new Point(164, 87); + grdLog.Name = "grdLog"; + grdLog.RowHeadersWidth = 51; + grdLog.Size = new Size(1000, 638); + grdLog.TabIndex = 4; + // + // Col5 + // + dataGridViewCellStyle8.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col5.DefaultCellStyle = dataGridViewCellStyle8; + Col5.Frozen = true; + Col5.HeaderText = "일시"; + Col5.MinimumWidth = 6; + Col5.Name = "Col5"; + Col5.Width = 220; + // + // Col0 + // + dataGridViewCellStyle9.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col0.DefaultCellStyle = dataGridViewCellStyle9; + Col0.Frozen = true; + Col0.HeaderText = "단말기명"; + Col0.MinimumWidth = 6; + Col0.Name = "Col0"; + Col0.Width = 170; + // + // Col3 + // + dataGridViewCellStyle10.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col3.DefaultCellStyle = dataGridViewCellStyle10; + Col3.Frozen = true; + Col3.HeaderText = "명령 유형"; + Col3.MinimumWidth = 6; + Col3.Name = "Col3"; + Col3.Width = 125; + // + // Col4 + // + dataGridViewCellStyle11.Alignment = DataGridViewContentAlignment.MiddleCenter; + Col4.DefaultCellStyle = dataGridViewCellStyle11; + Col4.Frozen = true; + Col4.HeaderText = "수행자"; + Col4.MinimumWidth = 6; + Col4.Name = "Col4"; + Col4.Width = 125; + // + // Col6 + // + Col6.Frozen = true; + Col6.HeaderText = "결과"; + Col6.MinimumWidth = 6; + Col6.Name = "Col6"; + Col6.Width = 125; + // + // Col7 + // + Col7.Frozen = true; + Col7.HeaderText = "상세내용"; + Col7.MinimumWidth = 6; + Col7.Name = "Col7"; + Col7.Width = 285; + // + // btnPrev + // + btnPrev.Font = new Font("맑은 고딕", 10.2F, FontStyle.Bold, GraphicsUnit.Point, 129); + btnPrev.Location = new Point(164, 12); + btnPrev.Name = "btnPrev"; + btnPrev.Size = new Size(174, 56); + btnPrev.TabIndex = 13; + btnPrev.Text = "이전"; + btnPrev.UseVisualStyleBackColor = true; + btnPrev.MouseClick += btnPrev_MouseClick; + // + // Form4 + // + AutoScaleDimensions = new SizeF(9F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1357, 737); + Controls.Add(btnPrev); + Controls.Add(grdLog); + Name = "Form4"; + Text = "Form4"; + ((System.ComponentModel.ISupportInitialize)grdLog).EndInit(); + ResumeLayout(false); + } + + #endregion + + private DataGridView grdLog; + private DataGridViewTextBoxColumn Col5; + private DataGridViewTextBoxColumn Col0; + private DataGridViewTextBoxColumn Col3; + private DataGridViewTextBoxColumn Col4; + private DataGridViewTextBoxColumn Col6; + private DataGridViewTextBoxColumn Col7; + private Button btnPrev; + } +} \ No newline at end of file diff --git a/ControlServer/Form4.cs b/ControlServer/Form4.cs new file mode 100644 index 0000000..3745b0a --- /dev/null +++ b/ControlServer/Form4.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace ControlServer +{ + public partial class Form4 : Form + { + public Form4() + { + InitializeComponent(); + + grdLog.RowHeadersVisible = false; // 그리드 자동으로 생성되는 첫 번째 열 제거 + grdLog.AllowUserToAddRows = false; // 새 행 입력용 기본 로우 제거 + grdLog.EnableHeadersVisualStyles = false; // 헤더 기본 테마 사용 안 함 + grdLog.ColumnHeadersDefaultCellStyle.BackColor = Color.LightGray; // 헤더 배경색 + grdLog.ColumnHeadersHeight = 40; // 헤더 높이 + grdLog.RowHeadersVisible = false; // 행 헤더 제거 + grdLog.AllowUserToAddRows = false; // // 행 추가 금지 + grdLog.AllowUserToResizeRows = false; // 행 높이 조절 금지 + grdLog.AllowUserToResizeColumns = false; // 열 너비 조절 금지 + grdLog.ReadOnly = true; // 읽기 전용 + grdLog.ClearSelection(); + } + + private void btnPrev_MouseClick(object sender, MouseEventArgs e) + { + this.Close(); + } + } +} diff --git a/ControlServer/Form4.resx b/ControlServer/Form4.resx new file mode 100644 index 0000000..37e0ab2 --- /dev/null +++ b/ControlServer/Form4.resx @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + True + + + True + + + True + + + True + + + True + + + True + + \ No newline at end of file diff --git a/ControlServer/Popup.Designer.cs b/ControlServer/Popup.Designer.cs new file mode 100644 index 0000000..b0c5319 --- /dev/null +++ b/ControlServer/Popup.Designer.cs @@ -0,0 +1,82 @@ +namespace ControlServer +{ + partial class Popup + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + lblText = new Label(); + btnOk = new Button(); + SuspendLayout(); + // + // lblText + // + lblText.Font = new Font("맑은 고딕", 12F, FontStyle.Regular, GraphicsUnit.Point, 129); + lblText.ForeColor = Color.Black; + lblText.Location = new Point(71, 50); + lblText.Name = "lblText"; + lblText.Size = new Size(418, 139); + lblText.TabIndex = 0; + lblText.TextAlign = ContentAlignment.MiddleCenter; + // + // btnOk + // + btnOk.BackColor = SystemColors.Desktop; + btnOk.Font = new Font("맑은 고딕", 12F, FontStyle.Regular, GraphicsUnit.Point, 129); + btnOk.ForeColor = Color.White; + btnOk.Location = new Point(119, 235); + btnOk.Name = "btnOk"; + btnOk.Size = new Size(328, 62); + btnOk.TabIndex = 1; + btnOk.Text = "확인"; + btnOk.UseVisualStyleBackColor = false; + btnOk.MouseClick += btnOk_MouseClick; + // + // Popup + // + AutoScaleDimensions = new SizeF(9F, 20F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = SystemColors.Window; + ClientSize = new Size(558, 332); + Controls.Add(btnOk); + Controls.Add(lblText); + ForeColor = Color.Transparent; + FormBorderStyle = FormBorderStyle.None; + MaximizeBox = false; + MinimizeBox = false; + Name = "Popup"; + ShowInTaskbar = false; + StartPosition = FormStartPosition.CenterParent; + Text = "Popup"; + ResumeLayout(false); + } + + #endregion + + private Label lblText; + private Button btnOk; + } +} \ No newline at end of file diff --git a/ControlServer/Popup.cs b/ControlServer/Popup.cs new file mode 100644 index 0000000..f00efc8 --- /dev/null +++ b/ControlServer/Popup.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace ControlServer +{ + public partial class Popup : Form + { + public Popup(string message) + { + InitializeComponent(); + + lblText.Text = message; + } + + private void btnOk_MouseClick(object sender, MouseEventArgs e) + { + this.DialogResult = DialogResult.OK; // Form2에 이벤트 전달 + this.Close(); + } + } +} diff --git a/ControlServer/Popup.resx b/ControlServer/Popup.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ControlServer/Popup.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ControlServer/Program.cs b/ControlServer/Program.cs new file mode 100644 index 0000000..2ac4501 --- /dev/null +++ b/ControlServer/Program.cs @@ -0,0 +1,17 @@ +namespace ControlServer +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new Form1()); + } + } +} \ No newline at end of file diff --git a/ControlServer/Properties/Resources.Designer.cs b/ControlServer/Properties/Resources.Designer.cs new file mode 100644 index 0000000..a98024f --- /dev/null +++ b/ControlServer/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// 이 코드는 도구를 사용하여 생성되었습니다. +// 런타임 버전:4.0.30319.42000 +// +// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면 +// 이러한 변경 내용이 손실됩니다. +// +//------------------------------------------------------------------------------ + +namespace ControlServer.Properties { + using System; + + + /// + /// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다. + /// + // 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder + // 클래스에서 자동으로 생성되었습니다. + // 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을 + // 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ControlServer.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을 + /// 재정의합니다. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// System.Drawing.Bitmap 형식의 지역화된 리소스를 찾습니다. + /// + internal static System.Drawing.Bitmap button_search { + get { + object obj = ResourceManager.GetObject("button-search", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/ControlServer/Properties/Resources.resx b/ControlServer/Properties/Resources.resx new file mode 100644 index 0000000..dab1ac7 --- /dev/null +++ b/ControlServer/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\button-search.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/ControlServer/Resources/button-search.png b/ControlServer/Resources/button-search.png new file mode 100644 index 0000000..5cca2a3 Binary files /dev/null and b/ControlServer/Resources/button-search.png differ diff --git a/ControlServer/TerminalInfo.cs b/ControlServer/TerminalInfo.cs new file mode 100644 index 0000000..8964f2c --- /dev/null +++ b/ControlServer/TerminalInfo.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ControlServer +{ + public class TerminalInfo + { + public string TerminalName { get; set; } = ""; + + public string IP { get; set; } = ""; + + public string Port { get; set; } = ""; + + public string Mac { get; set; } = ""; + + public string Path { get; set; } = ""; + + public string ProcessName { get; set; } = ""; + } +}