From 2d8a3b098777f60d5645aae9caaa864e5fa41d92 Mon Sep 17 00:00:00 2001 From: seuuung Date: Mon, 3 Aug 2026 11:02:21 +0900 Subject: [PATCH] =?UTF-8?q?QR=20=EC=8A=A4=EC=BA=94=ED=9B=84=20=ED=8C=8C?= =?UTF-8?q?=EC=97=85=20=EC=9E=90=EB=8F=99=20=EB=8B=AB=ED=9E=98,=20?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=ED=99=94=EB=A9=B4=EC=97=90=20=EC=8A=A4?= =?UTF-8?q?=EC=BA=94=20=EA=B0=92=20=ED=91=9C=EC=8B=9C,=20PCB=20Barcode=20?= =?UTF-8?q?=ED=91=9C=EA=B8=B0=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=93=B1=20=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vs/marking_gui.slnx/v18/.suo | Bin 92160 -> 92160 bytes .../v18/DocumentLayout.backup.json | 34 +- .vs/marking_gui.slnx/v18/DocumentLayout.json | 34 +- docs/developer_manual.md | 2 +- marking_gui.Setup/Bundle.wxs | 4 +- marking_gui/App.xaml.cs | 28 + marking_gui/MainWindow.xaml | 49 +- marking_gui/MainWindow.xaml.cs | 487 +++++++----------- marking_gui/Manual/01_시스템_개요.md | 4 +- marking_gui/Manual/03_메인_화면.md | 11 +- marking_gui/Manual/04_통신_설정.md | 4 + marking_gui/Manual/07_시험_프로세스.md | 18 +- marking_gui/Manual/09_오류_대응.md | 6 + marking_gui/Manual/Manual_Merged.md | 229 ++------ marking_gui/Manual/Manual_for_pdf.html | 238 ++------- marking_gui/Models/Product.cs | 2 +- marking_gui/PortSettingsWindow.xaml | 101 ++-- marking_gui/PortSettingsWindow.xaml.cs | 163 ++++-- marking_gui/QrVerificationWindow.xaml | 88 ++++ marking_gui/QrVerificationWindow.xaml.cs | 284 ++++++++++ .../Services/BarcodeScannerSettings.cs | 163 ++++++ marking_gui/Services/DatabaseService.cs | 71 ++- marking_gui/Services/LoginServicesStub.cs | 41 +- marking_gui/Services/SerialBarcodeScanner.cs | 263 ++++++++++ marking_gui/Setting.ini | 19 +- marking_gui/SettingsWindow.xaml | 79 +-- marking_gui/SettingsWindow.xaml.cs | 2 +- marking_gui/StartupLoginWindow.xaml.cs | 100 +++- program_flow.md | 11 +- 29 files changed, 1629 insertions(+), 906 deletions(-) create mode 100644 marking_gui/QrVerificationWindow.xaml create mode 100644 marking_gui/QrVerificationWindow.xaml.cs create mode 100644 marking_gui/Services/BarcodeScannerSettings.cs create mode 100644 marking_gui/Services/SerialBarcodeScanner.cs diff --git a/.vs/marking_gui.slnx/v18/.suo b/.vs/marking_gui.slnx/v18/.suo index 8c54e72fa0dc37a562192f506fe9d00784b50731..630793541705f3ba55626fc8faabd511bce25f85 100644 GIT binary patch delta 12418 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 XVByc+hl=m)-u{e_zcao8aO1xLj1$(Y delta 11476 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 diff --git a/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json b/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json index 165fc2d..f151ae1 100644 --- a/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json +++ b/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json @@ -5,6 +5,14 @@ { "AbsoluteMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|c:\\users\\computer1\\desktop\\mobi\\marking_gui\\marking_gui\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", "RelativeMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|solutionrelative:marking_gui\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|c:\\users\\computer1\\desktop\\mobi\\marking_gui\\marking_gui\\qrverificationwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|solutionrelative:marking_gui\\qrverificationwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|c:\\users\\computer1\\desktop\\mobi\\marking_gui\\marking_gui\\settingswindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|solutionrelative:marking_gui\\settingswindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" } ], "DocumentGroupContainers": [ @@ -14,12 +22,36 @@ "DocumentGroups": [ { "DockedWidth": 200, - "SelectedChildIndex": 1, + "SelectedChildIndex": 3, "Children": [ { "$type": "Bookmark", "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}" }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "QrVerificationWindow.xaml", + "DocumentMoniker": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\QrVerificationWindow.xaml", + "RelativeDocumentMoniker": "marking_gui\\QrVerificationWindow.xaml", + "ToolTip": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\QrVerificationWindow.xaml", + "RelativeToolTip": "marking_gui\\QrVerificationWindow.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-07-29T04:12:09.69Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "SettingsWindow.xaml", + "DocumentMoniker": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\SettingsWindow.xaml", + "RelativeDocumentMoniker": "marking_gui\\SettingsWindow.xaml", + "ToolTip": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\SettingsWindow.xaml", + "RelativeToolTip": "marking_gui\\SettingsWindow.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-07-29T04:12:06.926Z", + "EditorCaption": "" + }, { "$type": "Document", "DocumentIndex": 0, diff --git a/.vs/marking_gui.slnx/v18/DocumentLayout.json b/.vs/marking_gui.slnx/v18/DocumentLayout.json index 165fc2d..f151ae1 100644 --- a/.vs/marking_gui.slnx/v18/DocumentLayout.json +++ b/.vs/marking_gui.slnx/v18/DocumentLayout.json @@ -5,6 +5,14 @@ { "AbsoluteMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|c:\\users\\computer1\\desktop\\mobi\\marking_gui\\marking_gui\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", "RelativeMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|solutionrelative:marking_gui\\mainwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|c:\\users\\computer1\\desktop\\mobi\\marking_gui\\marking_gui\\qrverificationwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|solutionrelative:marking_gui\\qrverificationwindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" + }, + { + "AbsoluteMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|c:\\users\\computer1\\desktop\\mobi\\marking_gui\\marking_gui\\settingswindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}", + "RelativeMoniker": "D:0:0:{9E96D5BE-9375-4ED3-82DE-F200F83EBC2F}|marking_gui\\marking_gui.csproj|solutionrelative:marking_gui\\settingswindow.xaml||{F11ACC28-31D1-4C80-A34B-F4E09D3D753C}" } ], "DocumentGroupContainers": [ @@ -14,12 +22,36 @@ "DocumentGroups": [ { "DockedWidth": 200, - "SelectedChildIndex": 1, + "SelectedChildIndex": 3, "Children": [ { "$type": "Bookmark", "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}" }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "QrVerificationWindow.xaml", + "DocumentMoniker": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\QrVerificationWindow.xaml", + "RelativeDocumentMoniker": "marking_gui\\QrVerificationWindow.xaml", + "ToolTip": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\QrVerificationWindow.xaml", + "RelativeToolTip": "marking_gui\\QrVerificationWindow.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-07-29T04:12:09.69Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "SettingsWindow.xaml", + "DocumentMoniker": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\SettingsWindow.xaml", + "RelativeDocumentMoniker": "marking_gui\\SettingsWindow.xaml", + "ToolTip": "C:\\Users\\COMPUTER1\\Desktop\\mobi\\marking_gui\\marking_gui\\SettingsWindow.xaml", + "RelativeToolTip": "marking_gui\\SettingsWindow.xaml", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003549|", + "WhenOpened": "2026-07-29T04:12:06.926Z", + "EditorCaption": "" + }, { "$type": "Document", "DocumentIndex": 0, diff --git a/docs/developer_manual.md b/docs/developer_manual.md index c668be9..8b1f1c9 100644 --- a/docs/developer_manual.md +++ b/docs/developer_manual.md @@ -56,7 +56,7 @@ LotNoTag=YYMMDD ; 제품 모델명 (Product Name) 치환 태그 ProductTag=PRODUCT -; 2D QR 코드 데이터 치환 태그 +; QR 코드 데이터 치환 태그 QrCodeTag=QRCODETAG ; 검사 라인 코드 치환 태그 diff --git a/marking_gui.Setup/Bundle.wxs b/marking_gui.Setup/Bundle.wxs index e4077c1..d951c8c 100644 --- a/marking_gui.Setup/Bundle.wxs +++ b/marking_gui.Setup/Bundle.wxs @@ -1,8 +1,8 @@ - + - + diff --git a/marking_gui/App.xaml.cs b/marking_gui/App.xaml.cs index 36ae1aa..5a0d098 100644 --- a/marking_gui/App.xaml.cs +++ b/marking_gui/App.xaml.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Configuration; using System.Data; using System.Linq; +using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -13,11 +14,26 @@ namespace marking_gui /// public partial class App : Application { + private static Mutex? _mutex = null; + [System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)] private static extern bool SetDllDirectory(string lpPathName); protected override void OnStartup(StartupEventArgs e) { + // 전역 Mutex 생성으로 프로그램 중복 실행 원천 방지 + const string appName = "MarkingGui_SingleInstance_Mutex_9921"; + bool createdNew; + + _mutex = new Mutex(true, appName, out createdNew); + + if (!createdNew) + { + MessageBox.Show("프로그램이 이미 실행 중입니다.\n\n중복 실행할 수 없습니다.", "중복 실행 방지", MessageBoxButton.OK, MessageBoxImage.Warning); + Application.Current.Shutdown(); + return; + } + // 바로가기 등으로 실행 시 작업 디렉토리가 꼬이는 현상을 방지하기 위해 작업 디렉토리를 실행 파일 폴더로 강제 동기화 try { @@ -59,6 +75,18 @@ namespace marking_gui protected override void OnExit(ExitEventArgs e) { Services.LoggerService.Info("=================== [프로그램 정상 종료] ==================="); + + if (_mutex != null) + { + try + { + _mutex.ReleaseMutex(); + _mutex.Dispose(); + } + catch { } + _mutex = null; + } + base.OnExit(e); } diff --git a/marking_gui/MainWindow.xaml b/marking_gui/MainWindow.xaml index 861f332..a4c8c69 100644 --- a/marking_gui/MainWindow.xaml +++ b/marking_gui/MainWindow.xaml @@ -281,7 +281,7 @@ - + @@ -298,8 +298,14 @@ - - + + + + + + + + @@ -462,31 +468,38 @@ - + - - + + - + + + + + + + + - - + + - - + + - - + + - + - + - + @@ -560,8 +573,8 @@