- UIControl 프로젝트 구조 변경 (CapCleaningControl → Sub/UIControl) - arAjinextek 라이브러리 통합 및 구조 개선 - 새로운 arAjinextek_Union 프로젝트 추가 - 솔루션 파일에 README.md 추가 - QR 모드에서 WMS RCV 태그 인식 기능 강화 - 데이터베이스 스키마 업데이트 및 관련 클래스 수정 - 프린터 및 바코드 장치 연동 로직 개선 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
153 lines
5.2 KiB
C#
153 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Resources;
|
|
using System.Threading;
|
|
using AR;
|
|
using System.Security.Principal;
|
|
using System.Diagnostics;
|
|
|
|
namespace Project
|
|
{
|
|
static class Program
|
|
{
|
|
/// <summary>
|
|
/// 해당 응용 프로그램의 주 진입점입니다.
|
|
/// </summary>
|
|
[STAThread]
|
|
static void Main()
|
|
{
|
|
|
|
|
|
Application.EnableVisualStyles();
|
|
Application.SetCompatibleTextRenderingDefault(false);
|
|
|
|
if (CheckSingleInstance() == false) return;
|
|
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
|
|
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
|
Application.Run(new FMain());
|
|
}
|
|
|
|
static bool IsAdmin()
|
|
{
|
|
var identy = WindowsIdentity.GetCurrent();
|
|
if (identy != null)
|
|
{
|
|
var princ = new WindowsPrincipal(identy);
|
|
return princ.IsInRole(WindowsBuiltInRole.Administrator);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 중복실행 방지 체크
|
|
/// </summary>
|
|
/// <returns>단일 인스턴스인 경우 true, 중복실행인 경우 false</returns>
|
|
static bool CheckSingleInstance()
|
|
{
|
|
string processName = Process.GetCurrentProcess().ProcessName;
|
|
Process[] processes = Process.GetProcessesByName(processName);
|
|
|
|
if (processes.Length > 1)
|
|
{
|
|
// 중복실행 감지
|
|
string message = $"⚠️ {Application.ProductName} 프로그램이 이미 실행 중입니다!\n\n" +
|
|
"동시에 여러 개의 프로그램을 실행할 수 없습니다.\n\n" +
|
|
"해결방법을 선택하세요:";
|
|
|
|
var result = MessageBox.Show(message + "\n\n예(Y): 기존 프로그램을 종료하고 새로 시작\n아니오(N): 현재 실행을 취소",
|
|
"중복실행 감지",
|
|
MessageBoxButtons.YesNo,
|
|
MessageBoxIcon.Warning);
|
|
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
// 기존 프로세스들을 종료
|
|
try
|
|
{
|
|
int currentProcessId = Process.GetCurrentProcess().Id;
|
|
foreach (Process process in processes)
|
|
{
|
|
if (process.Id != currentProcessId)
|
|
{
|
|
process.Kill();
|
|
process.WaitForExit(3000); // 3초 대기
|
|
}
|
|
}
|
|
|
|
// 잠시 대기 후 계속 진행
|
|
Thread.Sleep(1000);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"기존 프로그램 종료 중 오류가 발생했습니다:\n{ex.Message}\n\n" +
|
|
"작업관리자에서 수동으로 종료해주세요.",
|
|
"오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 현재 실행을 취소
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true; // 단일 인스턴스
|
|
}
|
|
|
|
|
|
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
|
{
|
|
|
|
string emsg = "Fatal Error(UHE)\n\n" + e.ExceptionObject.ToString();
|
|
if (PUB.log != null)
|
|
{
|
|
PUB.log.AddE(emsg);
|
|
PUB.log.Flush();
|
|
}
|
|
|
|
|
|
UTIL.SaveBugReport(emsg);
|
|
Shutdown();
|
|
|
|
using (var f = new AR.Dialog.fErrorException(emsg))
|
|
f.ShowDialog();
|
|
Application.ExitThread();
|
|
}
|
|
|
|
static void Shutdown()
|
|
{
|
|
PUB.dio.SetOutput(false); //모두끄기
|
|
PUB.sm.SetNewStep(eSMStep.IDLE, true);
|
|
PUB.flag.set(eVarBool.FG_USERSTEP, false, "shutdown");
|
|
PUB.log.Add("Program Close");
|
|
PUB.log.Flush();
|
|
PUB.dio.StopMonitor();
|
|
PUB.mot.StopMonitor();
|
|
PUB.sm.Stop();
|
|
|
|
}
|
|
|
|
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
|
|
{
|
|
|
|
string emsg = "Fatal Error(ATE)\n\n" + e.Exception.ToString();
|
|
if(PUB.log != null)
|
|
{
|
|
PUB.log.AddE(emsg);
|
|
PUB.log.Flush();
|
|
}
|
|
UTIL.SaveBugReport(emsg);
|
|
Shutdown();
|
|
using (var f = new AR.Dialog.fErrorException(emsg))
|
|
f.ShowDialog();
|
|
Application.ExitThread();
|
|
}
|
|
}
|
|
}
|