Browse Source

버그 수정

main
최승민 1 month ago
parent
commit
a48c4a2f35
  1. 2
      DB/dbo.EOL_Schema.sql
  2. 13
      leak_test_project.Setup/Bundle.wxs
  3. 62
      leak_test_project.Setup/Product.wxs
  4. 8
      leak_test_project/App.xaml.cs
  5. 13
      leak_test_project/Properties/PublishProfiles/ClickOnceProfile.pubxml
  6. 7
      leak_test_project/Properties/PublishProfiles/ClickOnceProfile.pubxml.user
  7. 7
      leak_test_project/Properties/PublishProfiles/FolderProfile.pubxml
  8. 2
      leak_test_project/Properties/PublishProfiles/FolderProfile.pubxml.user
  9. 19
      leak_test_project/Services/DatabaseSettings.cs
  10. 1
      leak_test_project/Services/TestProcessService.cs
  11. 108
      leak_test_project/leak_test_project.csproj
  12. 16
      ob/05_Implementation_History.md
  13. 11
      ob/db_login_integration.md

2
DB/dbo.EOL_Schema.sql

@ -37,7 +37,7 @@ CREATE TABLE [dbo].[EOL] (
[Variant_2] NVARCHAR(10) NULL, -- 로그인 변형2 정보 [Variant_2] NVARCHAR(10) NULL, -- 로그인 변형2 정보
[Operator] NVARCHAR(10) NOT NULL, -- 로그인 검사자 ID [Operator] NVARCHAR(10) NOT NULL, -- 로그인 검사자 ID
[Production_Date] DATETIME2(0) NOT NULL DEFAULT GETDATE(), -- 검사 일시 [Production_Date] DATETIME2(0) NOT NULL DEFAULT GETDATE(), -- 검사 일시
[Line] NVARCHAR(5) NULL, -- 로그인 작업 라인 [Line] NVARCHAR(30) NULL, -- 로그인 작업 라인
[Lot_No] NVARCHAR(8) NULL, -- 로그인 Lot 번호 [Lot_No] NVARCHAR(8) NULL, -- 로그인 Lot 번호
[Jig_No] NVARCHAR(10) NULL, -- 로그인 지그 번호 [Jig_No] NVARCHAR(10) NULL, -- 로그인 지그 번호
[Channel] NVARCHAR(5) NOT NULL, -- 검증 수행 채널 (LEFT / RIGHT) [Channel] NVARCHAR(5) NOT NULL, -- 검증 수행 채널 (LEFT / RIGHT)

13
leak_test_project.Setup/Bundle.wxs

@ -0,0 +1,13 @@
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
<Bundle Name="Leak Test System" Version="1.0.0" Manufacturer="MobiDigm" UpgradeCode="d2c8d0f1-4df2-4752-9b24-7f154562c5b4">
<BootstrapperApplication>
<bal:WixStandardBootstrapperApplication LicenseUrl="https://www.mobidigm.co.kr" Theme="hyperlinkLicense" SuppressOptionsUI="yes" />
</BootstrapperApplication>
<Chain>
<!-- 빌드 프로세스 하위에 생성된 MSI 패키지를 래핑 -->
<MsiPackage SourceFile="C:\LeakTest\LeakTestSetup.msi" Compressed="yes" Vital="yes" />
</Chain>
</Bundle>
</Wix>

62
leak_test_project.Setup/Product.wxs

@ -1,13 +1,59 @@
<?xml version="1.0" encoding=
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Product Id="*" Name="leak_test_project" Language="1033" Version="1.0.0.0" Manufacturer="MobiDigm" UpgradeCode="12345678-1234-1234-1234-123456789012"> <Package Name="Leak Test System" Language="1042" Version="1.0.0" Manufacturer="MobiDigm" UpgradeCode="e1c8d0f1-4df2-4752-9b24-7f154562c5b3" Scope="perMachine">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<Media Id="1" Cabinet="cab1.cab" EmbedCab="yes" /> <MajorUpgrade DowngradeErrorMessage="이미 최신 버전의 프로그램이 설치되어 있습니다." />
<Directory Id="TARGETDIR" Name="SourceDir">
"UTF-8"?> <Directory Id="ProgramFilesFolder" /> <MediaTemplate EmbedCab="yes" />
<!-- 바탕화면 바로가기를 위한 DesktopFolder 참조용 표준 폴더 선언 -->
<StandardDirectory Id="DesktopFolder" />
<!-- C 드라이브 루트 하위에 LeakTest 폴더 생성 강제 고정 -->
<StandardDirectory Id="TARGETDIR" />
<SetDirectory Id="LeakTestFolder" Value="C:\LeakTest" />
<Directory Id="LeakTestFolder">
<!-- libs 폴더 제거: DllImport는 EXE 실행 폴더에서 검색하므로 루트에 DLL 배치 -->
<Directory Id="LogsFolder" Name="Logs" />
</Directory> </Directory>
<Feature Id="ProductFeature" Title="leak_test_project" Level="1">
<ComponentGroup Id="ProductComponents" Directory="LeakTestFolder">
<!-- 실행 파일 -->
<Component Id="MainExecutable" Guid="f128c312-d922-4824-811c-d760773d2aae">
<File Id="leak_test_project.exe" Source="C:\LeakTest\leak_test_project.exe" KeyPath="yes">
<!-- 바탕화면에 바로가기 생성 -->
<Shortcut Id="DesktopShortcut" Directory="DesktopFolder" Name="Leak Test System" WorkingDirectory="LeakTestFolder" Advertise="no" />
</File>
</Component>
<!-- 구성 파일 -->
<Component Id="ConfigFile" Guid="a76d8b9e-64bc-44d5-9118-2e02b781da22">
<File Id="leak_test_project.dll.config" Source="C:\LeakTest\leak_test_project.dll.config" KeyPath="yes" />
</Component>
<!-- DB 및 로그인 설정 파일 -->
<Component Id="DatabaseIni" Guid="d82b4a1b-32ba-4b2a-a924-f3c14a2bb3ee">
<File Id="Database.ini" Source="C:\LeakTest\Database.ini" KeyPath="yes" />
</Component>
<Component Id="LoginOptionsJson" Guid="c1a2d3e4-f5f6-4a4b-8c8d-9e9f0a0b0c0d">
<File Id="LoginOptions.json" Source="C:\LeakTest\LoginOptions.json" KeyPath="yes" />
</Component>
<!-- PCI-Dask.dll: [DllImport("PCI-Dask.dll")] 탐색 경로 = EXE 실행 폴더(루트)에 배치 필수 -->
<Component Id="PciDaskDll" Guid="b129a28c-c2df-424a-8bf8-d61b12b23a9a">
<File Id="PCI_Dask.dll" Source="C:\LeakTest\PCI-Dask.dll" KeyPath="yes" />
</Component>
<!-- Microsoft.Data.SqlClient.SNI.dll도 동일하게 루트에 배치 -->
<Component Id="SqlSniDll" Guid="c29a828d-d34e-42ef-abf9-c72b23c24b9b">
<File Id="Microsoft.Data.SqlClient.SNI.dll" Source="C:\LeakTest\Microsoft.Data.SqlClient.SNI.dll" KeyPath="yes" />
</Component>
</ComponentGroup>
<!-- 설치 대상 지정 -->
<Feature Id="ProductFeature" Title="Leak Test System Setup" Level="1">
<ComponentGroupRef Id="ProductComponents" /> <ComponentGroupRef Id="ProductComponents" />
</Feature> </Feature>
</Product> </Package>
</Wix> </Wix>

8
leak_test_project/App.xaml.cs

@ -35,10 +35,10 @@ namespace leak_test_project
"; Db_Name : 검사 데이터를 저장할 대상 데이터베이스 이름\r\n" + "; Db_Name : 검사 데이터를 저장할 대상 데이터베이스 이름\r\n" +
"; Db_User : 데이터베이스 접속 계정 ID (예: sa)\r\n" + "; Db_User : 데이터베이스 접속 계정 ID (예: sa)\r\n" +
"; Db_Password: 데이터베이스 접속 계정의 비밀번호\r\n" + "; Db_Password: 데이터베이스 접속 계정의 비밀번호\r\n" +
"Db_Server=192.168.0.20\r\n" + "Db_Server=192.168.10.10, 1433\r\n" +
"Db_Name=NE1aW_PT_SENSOR\r\n" + "Db_Name=NE1aW_PT_Sensor\r\n" +
"Db_User=sa\r\n" + "Db_User=su\r\n" +
"Db_Password=sa1234\r\n" + "Db_Password=amotech821\r\n" +
"\r\n" + "\r\n" +
"[Login]\r\n" + "[Login]\r\n" +
"; Procedure: 로그인 검증에 사용할 DB 저장 프로시저명입니다. (공란일 경우 기본 테이블 조회 쿼리 작동)\r\n" + "; Procedure: 로그인 검증에 사용할 DB 저장 프로시저명입니다. (공란일 경우 기본 테이블 조회 쿼리 작동)\r\n" +

13
leak_test_project/Properties/PublishProfiles/ClickOnceProfile.pubxml

@ -16,11 +16,11 @@
<OpenBrowserOnPublish>False</OpenBrowserOnPublish> <OpenBrowserOnPublish>False</OpenBrowserOnPublish>
<Platform>Any CPU</Platform> <Platform>Any CPU</Platform>
<PublishDir>bin\Release\net9.0-windows\win-x86\app.publish\</PublishDir> <PublishDir>bin\Release\net9.0-windows\win-x86\app.publish\</PublishDir>
<PublishUrl>C:\LeakTest\</PublishUrl> <PublishUrl>C:\Users\COMPUTER1\Downloads\</PublishUrl>
<PublishProtocol>ClickOnce</PublishProtocol> <PublishProtocol>ClickOnce</PublishProtocol>
<PublishReadyToRun>False</PublishReadyToRun> <PublishReadyToRun>False</PublishReadyToRun>
<PublishSingleFile>False</PublishSingleFile> <PublishSingleFile>True</PublishSingleFile>
<SelfContained>False</SelfContained> <SelfContained>True</SelfContained>
<SignatureAlgorithm>(없음)</SignatureAlgorithm> <SignatureAlgorithm>(없음)</SignatureAlgorithm>
<SignManifests>False</SignManifests> <SignManifests>False</SignManifests>
<SkipPublishVerification>false</SkipPublishVerification> <SkipPublishVerification>false</SkipPublishVerification>
@ -30,12 +30,5 @@
<UpdateRequired>False</UpdateRequired> <UpdateRequired>False</UpdateRequired>
<WebPageFileName>Publish.html</WebPageFileName> <WebPageFileName>Publish.html</WebPageFileName>
<RuntimeIdentifier>win-x86</RuntimeIdentifier> <RuntimeIdentifier>win-x86</RuntimeIdentifier>
<History>True|2026-06-30T02:34:09.3791223Z||;True|2026-06-30T10:59:48.1946670+09:00||;True|2026-06-30T10:33:19.5917230+09:00||;</History>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.NetCore.DesktopRuntime.9.0.x64">
<Install>True</Install>
<ProductName>.NET 데스크톱 런타임 9.0.17 (x64)</ProductName>
</BootstrapperPackage>
</ItemGroup>
</Project> </Project>

7
leak_test_project/Properties/PublishProfiles/ClickOnceProfile.pubxml.user

@ -1,8 +1,3 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. --> <!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project> <Project />
<PropertyGroup>
<History>True|2026-06-30T03:18:17.3581118Z||;True|2026-06-30T11:34:09.3791223+09:00||;True|2026-06-30T10:59:48.1946670+09:00||;True|2026-06-30T10:33:19.5917230+09:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>

7
leak_test_project/Properties/PublishProfiles/FolderProfile.pubxml

@ -1,16 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. --> <!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Any CPU</Platform> <Platform>Any CPU</Platform>
<PublishDir>C:\LeakTest\</PublishDir> <PublishDir>C:\Users\COMPUTER1\Downloads</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol> <PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId> <_TargetId>Folder</_TargetId>
<TargetFramework>net9.0-windows</TargetFramework> <TargetFramework>net9.0-windows</TargetFramework>
<SelfContained>false</SelfContained> <SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x86</RuntimeIdentifier> <RuntimeIdentifier>win-x86</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun> <PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

2
leak_test_project/Properties/PublishProfiles/FolderProfile.pubxml.user

@ -2,7 +2,7 @@
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. --> <!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<History>True|2026-07-01T02:40:58.7303122Z||;True|2026-07-01T10:52:14.8628105+09:00||;True|2026-07-01T10:45:31.8793742+09:00||;True|2026-07-01T10:35:19.6809435+09:00||;True|2026-07-01T10:35:00.9643317+09:00||;True|2026-07-01T10:32:31.0544609+09:00||;True|2026-07-01T10:25:33.3316628+09:00||;True|2026-07-01T10:23:02.2841540+09:00||;True|2026-07-01T10:19:59.2997126+09:00||;False|2026-07-01T10:17:21.1004186+09:00||;False|2026-06-30T10:32:04.0883654+09:00||;True|2026-06-30T10:24:54.7745409+09:00||;True|2026-06-25T14:28:15.0458856+09:00||;True|2026-06-25T13:57:36.3233571+09:00||;True|2026-06-25T12:56:04.8828587+09:00||;</History> <History>True|2026-07-02T02:10:03.3205130Z||;True|2026-07-02T10:57:07.7675289+09:00||;True|2026-07-02T10:48:02.4094102+09:00||;True|2026-07-02T10:47:32.3161255+09:00||;True|2026-07-02T09:56:10.5544859+09:00||;True|2026-07-01T16:42:19.4986373+09:00||;True|2026-07-01T16:30:40.3015254+09:00||;True|2026-07-01T16:15:05.1946766+09:00||;True|2026-07-01T16:14:42.7624440+09:00||;True|2026-07-01T16:10:15.7662884+09:00||;True|2026-07-01T11:40:58.7303122+09:00||;True|2026-07-01T10:52:14.8628105+09:00||;True|2026-07-01T10:45:31.8793742+09:00||;True|2026-07-01T10:35:19.6809435+09:00||;True|2026-07-01T10:35:00.9643317+09:00||;True|2026-07-01T10:32:31.0544609+09:00||;True|2026-07-01T10:25:33.3316628+09:00||;True|2026-07-01T10:23:02.2841540+09:00||;True|2026-07-01T10:19:59.2997126+09:00||;False|2026-07-01T10:17:21.1004186+09:00||;False|2026-06-30T10:32:04.0883654+09:00||;True|2026-06-30T10:24:54.7745409+09:00||;True|2026-06-25T14:28:15.0458856+09:00||;True|2026-06-25T13:57:36.3233571+09:00||;True|2026-06-25T12:56:04.8828587+09:00||;</History>
<LastFailureDetails /> <LastFailureDetails />
</PropertyGroup> </PropertyGroup>
</Project> </Project>

19
leak_test_project/Services/DatabaseSettings.cs

@ -26,16 +26,29 @@ namespace Housing.Services
{ {
get get
{ {
string connStr;
// 개별 설정이 모두 지정되어 있는 경우 조합해서 사용 // 개별 설정이 모두 지정되어 있는 경우 조합해서 사용
if (!string.IsNullOrWhiteSpace(Db_Server) && if (!string.IsNullOrWhiteSpace(Db_Server) &&
!string.IsNullOrWhiteSpace(Db_Name) && !string.IsNullOrWhiteSpace(Db_Name) &&
!string.IsNullOrWhiteSpace(Db_User) && !string.IsNullOrWhiteSpace(Db_User) &&
!string.IsNullOrWhiteSpace(Db_Password)) !string.IsNullOrWhiteSpace(Db_Password))
{ {
return $"Server={Db_Server};Database={Db_Name};User Id={Db_User};Password={Db_Password};"; connStr = $"Server={Db_Server};Database={Db_Name};User Id={Db_User};Password={Db_Password};";
} }
// 없으면 레거시 ConnectionString 필드를 그대로 사용 else
return _rawConnectionString; {
// 없으면 레거시 ConnectionString 필드를 그대로 사용
connStr = _rawConnectionString;
}
// SSL 인증서 체인 신뢰성 오류(TrustServerCertificate=True 누락) 방지 조치 추가
if (!string.IsNullOrWhiteSpace(connStr) && connStr.IndexOf("TrustServerCertificate", StringComparison.OrdinalIgnoreCase) < 0)
{
if (!connStr.EndsWith(";")) connStr += ";";
connStr += "TrustServerCertificate=True;";
}
return connStr;
} }
set set
{ {

1
leak_test_project/Services/TestProcessService.cs

@ -285,6 +285,7 @@ namespace leak_test_project.Services
ProductionDate = DateTime.Now ProductionDate = DateTime.Now
}); });
continue;
} }
// === 1.5단계: PCB 바코드 DB 조회 (dbo.Housing_Assembly) === // === 1.5단계: PCB 바코드 DB 조회 (dbo.Housing_Assembly) ===

108
leak_test_project/leak_test_project.csproj

@ -11,6 +11,14 @@
<PlatformTarget>x86</PlatformTarget> <PlatformTarget>x86</PlatformTarget>
<Platforms>AnyCPU;x86</Platforms> <Platforms>AnyCPU;x86</Platforms>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<!-- 단일 파일 배포 및 정제 설정 -->
<PublishSingleFile>true</PublishSingleFile>
<!-- SelfContained=true: 대상 PC의 .NET 런타임 설치 여부와 무관하게 실행 가능 -->
<SelfContained>true</SelfContained>
<!-- 네이티브 DLL들도 단일 EXE 안에 내장하여 추출 방식으로 처리 -->
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -25,6 +33,9 @@
<None Update="Database.ini"> <None Update="Database.ini">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="Sensor.ini">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="PCI-Dask.dll"> <None Update="PCI-Dask.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
@ -33,8 +44,101 @@
</None> </None>
</ItemGroup> </ItemGroup>
<Target Name="MakeLogsFolder" AfterTargets="Publish"> <!-- 빌드 후 Native DLL을 libs 하위 폴더로 복사 (XCopy 플랫폼 의존성 배제) -->
<MakeDir Directories="C:\LeakTest\Logs" /> <Target Name="CopyDllToLibs" AfterTargets="Build">
<ItemGroup>
<NativeDlls Include="$(TargetDir)PCI-Dask.dll" />
</ItemGroup>
<MakeDir Directories="$(TargetDir)libs" Condition="!Exists('$(TargetDir)libs')" />
<Copy SourceFiles="@(NativeDlls)" DestinationFolder="$(TargetDir)libs\" SkipUnchangedFiles="true" />
</Target>
<!-- Publish 단계 완료 후 Native DLL을 libs 하위 폴더로 복사 -->
<Target Name="CopyDllToPublish" AfterTargets="Publish">
<ItemGroup>
<PublishNativeDlls Include="$(MSBuildProjectDirectory)\PCI-Dask.dll" />
</ItemGroup>
<MakeDir Directories="$(PublishDir)libs" Condition="!Exists('$(PublishDir)libs')" />
<Copy SourceFiles="@(PublishNativeDlls)" DestinationFolder="$(PublishDir)libs\" SkipUnchangedFiles="true" />
</Target>
<!-- C:\LeakTest\ 설치 전용 Target (Publish에 의존하며, PublishDir로부터 복사 실행) -->
<Target Name="FolderPublish" DependsOnTargets="Publish" AfterTargets="Publish">
<PropertyGroup>
<DeployTargetFolder>C:\LeakTest\</DeployTargetFolder>
<PublishBackupDir>$(MSBuildProjectDirectory)\bin\Release\net9.0-windows\win-x86\publish_backup\</PublishBackupDir>
</PropertyGroup>
<Message Text="Deploying clean publish output to $(DeployTargetFolder)..." Importance="high" />
<!-- 기존 대상 디렉토리 클린업 및 재생성 (지저분한 기존 dll 파일들 소거) -->
<RemoveDir Directories="$(DeployTargetFolder)" />
<MakeDir Directories="$(DeployTargetFolder)" />
<MakeDir Directories="$(DeployTargetFolder)Logs" />
<!-- 실행 파일, 런타임 구성 파일 복사 -->
<Copy SourceFiles="$(PublishDir)leak_test_project.exe" DestinationFolder="$(DeployTargetFolder)" />
<Copy SourceFiles="$(TargetDir)leak_test_project.dll.config" DestinationFolder="$(DeployTargetFolder)" />
<!-- 설정 파일 복사 (프로젝트 소스에서 직접 이관) -->
<Copy SourceFiles="$(MSBuildProjectDirectory)\Database.ini" DestinationFolder="$(DeployTargetFolder)" />
<Copy SourceFiles="$(MSBuildProjectDirectory)\LoginOptions.json" DestinationFolder="$(DeployTargetFolder)" />
<Copy SourceFiles="$(MSBuildProjectDirectory)\Sensor.ini" DestinationFolder="$(DeployTargetFolder)" Condition="Exists('$(MSBuildProjectDirectory)\Sensor.ini')" />
<!-- Native DLLs 복사: [DllImport("PCI-Dask.dll")] 검색 경로는 EXE 실행 폴더(루트)이므로 루트에 배치 -->
<Copy SourceFiles="$(MSBuildProjectDirectory)\PCI-Dask.dll" DestinationFolder="$(DeployTargetFolder)" />
<Copy SourceFiles="$(TargetDir)Microsoft.Data.SqlClient.SNI.dll" DestinationFolder="$(DeployTargetFolder)" />
<!-- [WiX Toolset 단일 MSI 설치 파일 자동 빌드 스텝] -->
<Message Text="Compiling single installer MSI via WiX Toolset..." Importance="high" />
<Exec Command="wix build &quot;$(MSBuildProjectDirectory)\..\leak_test_project.Setup\Product.wxs&quot; -o &quot;$(DeployTargetFolder)LeakTestSetup.msi&quot;" WorkingDirectory="$(MSBuildProjectDirectory)" />
<!-- [WiX Toolset 단일 EXE 설치 파일 자동 빌드 스텝] -->
<Message Text="Compiling single installer EXE via WiX Toolset Bundle..." Importance="high" />
<Exec Command="wix build &quot;$(MSBuildProjectDirectory)\..\leak_test_project.Setup\Bundle.wxs&quot; -o &quot;$(DeployTargetFolder)LeakTestSetup.exe&quot; -ext WixToolset.BootstrapperApplications.wixext/5.0.2" WorkingDirectory="$(MSBuildProjectDirectory)" />
<!-- 빌드 중간 산출물 .wixpdb 및 MSI 파일 정리 (C:\LeakTest 폴더 깔끔화) -->
<Delete Files="$(DeployTargetFolder)LeakTestSetup.wixpdb" />
<Delete Files="$(DeployTargetFolder)LeakTestSetup.msi" />
<!-- 비주얼 스튜디오 게시 출력 폴더(PublishDir) 정화 작업 -->
<Message Text="Purging publish output directory and leaving only LeakTestSetup.exe..." Importance="high" />
<!-- 1. LeakTestSetup.exe 파일을 임시 대피 경로로 복사 -->
<RemoveDir Directories="$(PublishBackupDir)" />
<MakeDir Directories="$(PublishBackupDir)" />
<Copy SourceFiles="$(DeployTargetFolder)LeakTestSetup.exe" DestinationFolder="$(PublishBackupDir)" />
<!-- 2. 게시 폴더(PublishDir) 하위의 모든 자원 삭제 (dll, config, json, exe, libs 폴더 등) -->
<ItemGroup>
<FilesToClean Include="$(PublishDir)*.dll" />
<FilesToClean Include="$(PublishDir)*.exe" />
<FilesToClean Include="$(PublishDir)*.config" />
<FilesToClean Include="$(PublishDir)*.json" />
<FilesToClean Include="$(PublishDir)*.pdb" />
<FilesToClean Include="$(PublishDir)*.ini" />
</ItemGroup>
<Delete Files="@(FilesToClean)" />
<RemoveDir Directories="$(PublishDir)libs" />
<RemoveDir Directories="$(PublishDir)cs" />
<RemoveDir Directories="$(PublishDir)de" />
<RemoveDir Directories="$(PublishDir)es" />
<RemoveDir Directories="$(PublishDir)fr" />
<RemoveDir Directories="$(PublishDir)it" />
<RemoveDir Directories="$(PublishDir)ja" />
<RemoveDir Directories="$(PublishDir)ko" />
<RemoveDir Directories="$(PublishDir)pl" />
<RemoveDir Directories="$(PublishDir)pt-BR" />
<RemoveDir Directories="$(PublishDir)ru" />
<RemoveDir Directories="$(PublishDir)tr" />
<RemoveDir Directories="$(PublishDir)zh-Hans" />
<RemoveDir Directories="$(PublishDir)zh-Hant" />
<!-- 3. 대피시켰던 단일 설치 EXE 파일만 다시 게시 폴더(PublishDir)로 원복 이관 -->
<Copy SourceFiles="$(PublishBackupDir)LeakTestSetup.exe" DestinationFolder="$(PublishDir)" />
<!-- 4. 대피 임시 폴더 삭제 정리 -->
<RemoveDir Directories="$(PublishBackupDir)" />
<Message Text="Single Installer successfully compiled at both C:\LeakTest\LeakTestSetup.exe and $(PublishDir)LeakTestSetup.exe" Importance="high" />
</Target> </Target>
</Project> </Project>

16
ob/05_Implementation_History.md

@ -147,4 +147,20 @@
13. **메인 화면 제품 식별자 2개 행 분리 및 레이아웃 최적화**: 메인 화면인 `HomeView.xaml`의 좌/우 채널 모니터링 카드 내부 제품 ID 라벨에 대해 가로 텍스트 잘림 현상을 근본적으로 해결하기 위해, 기존 단일 `"ID"` 행을 **`"IC_SN"`**과 **`"PCB_Barcode"`**의 **2개 독립된 행(Rows)으로 완전히 분리**하고 각 값을 별개 라인에 실시간 바인딩 처리(`HomeViewModel.cs`)했습니다. 이를 통해 고정 헤더 가로폭을 늘리지 않고 기존의 깔끔한 가로폭 비율인 **`130`**을 유지하여 레이아웃의 완성도와 가독성을 보장했습니다. 또한 영문 `"PCB_Barcode"` 라벨 텍스트의 좌우 여백을 개별 마진 **`Margin="6,0"`**으로 미세 조율하여, 윈도우의 가로 크기를 최소 사양인 **`1150`**으로 줄인 창모드 상태에서도 단 1픽셀의 잘림 없이 모든 텍스트가 명확하게 표현되도록 방어했습니다. 13. **메인 화면 제품 식별자 2개 행 분리 및 레이아웃 최적화**: 메인 화면인 `HomeView.xaml`의 좌/우 채널 모니터링 카드 내부 제품 ID 라벨에 대해 가로 텍스트 잘림 현상을 근본적으로 해결하기 위해, 기존 단일 `"ID"` 행을 **`"IC_SN"`**과 **`"PCB_Barcode"`**의 **2개 독립된 행(Rows)으로 완전히 분리**하고 각 값을 별개 라인에 실시간 바인딩 처리(`HomeViewModel.cs`)했습니다. 이를 통해 고정 헤더 가로폭을 늘리지 않고 기존의 깔끔한 가로폭 비율인 **`130`**을 유지하여 레이아웃의 완성도와 가독성을 보장했습니다. 또한 영문 `"PCB_Barcode"` 라벨 텍스트의 좌우 여백을 개별 마진 **`Margin="6,0"`**으로 미세 조율하여, 윈도우의 가로 크기를 최소 사양인 **`1150`**으로 줄인 창모드 상태에서도 단 1픽셀의 잘림 없이 모든 텍스트가 명확하게 표현되도록 방어했습니다.
14. **배포 설정 파일 통합 및 C드라이브 배포 자동화**: 클릭원스 배포 시 파편화될 수 있는 설정 데이터의 안전한 관리를 위해, `LoginOptions.json``LoginHistory.json` 파일의 생성 및 조회 경로를 `Database.ini` 파일이 위치하는 공용 설정 폴더인 **`C:\ProgramData\LeakTest`**로 전면 일원화 조치(`StartupLoginWindow.xaml.cs`)했습니다. 추가로, 설치 프로그램 배포 패키지가 C드라이브 고정 위치에 생성되도록 `ClickOnceProfile.pubxml``PublishUrl`**`C:\LeakTest\`**로 변경하고, `leak_test_project.csproj` 내에 `PostPublishCopy` MSBuild target을 추가하여 클릭원스 배포 빌드 시 패키지 파일 일체가 `C:\LeakTest`로 자동 생성 및 이동(복사)되도록 빌드 자동화를 완벽 구현하였습니다. 14. **배포 설정 파일 통합 및 C드라이브 배포 자동화**: 클릭원스 배포 시 파편화될 수 있는 설정 데이터의 안전한 관리를 위해, `LoginOptions.json``LoginHistory.json` 파일의 생성 및 조회 경로를 `Database.ini` 파일이 위치하는 공용 설정 폴더인 **`C:\ProgramData\LeakTest`**로 전면 일원화 조치(`StartupLoginWindow.xaml.cs`)했습니다. 추가로, 설치 프로그램 배포 패키지가 C드라이브 고정 위치에 생성되도록 `ClickOnceProfile.pubxml``PublishUrl`**`C:\LeakTest\`**로 변경하고, `leak_test_project.csproj` 내에 `PostPublishCopy` MSBuild target을 추가하여 클릭원스 배포 빌드 시 패키지 파일 일체가 `C:\LeakTest`로 자동 생성 및 이동(복사)되도록 빌드 자동화를 완벽 구현하였습니다.
15. **대기 상태 진입 시 화면 초기화 및 상태 표시 개선**: 좌/우 채널에 신호가 거의 동시에 투입되어 한쪽 채널이 대기 상태에 들어갈 때, 레이스 컨디션으로 인해 이전 검사 결과가 화면에 그대로 남아있고 "대기중" 상태가 표시되지 않는 문제를 해결했습니다. `_testLock.CurrentCount == 0` 조건을 확인하는 대신 `_testLock.Wait(0)`을 이용하여 락 획득 가능 여부를 원자적(Atomic)으로 체크한 뒤, 획득에 실패했을 때만 화면을 비우고(`ResultClearRequested`) "대기중" 상태(`NotifyProgress`)로 전환 후 락을 대기하도록 로직을 개선했습니다. 15. **대기 상태 진입 시 화면 초기화 및 상태 표시 개선**: 좌/우 채널에 신호가 거의 동시에 투입되어 한쪽 채널이 대기 상태에 들어갈 때, 레이스 컨디션으로 인해 이전 검사 결과가 화면에 그대로 남아있고 "대기중" 상태가 표시되지 않는 문제를 해결했습니다. `_testLock.CurrentCount == 0` 조건을 확인하는 대신 `_testLock.Wait(0)`을 이용하여 락 획득 가능 여부를 원자적(Atomic)으로 체크한 뒤, 획득에 실패했을 때만 화면을 비우고(`ResultClearRequested`) "대기중" 상태(`NotifyProgress`)로 전환 후 락을 대기하도록 로직을 개선했습니다.
16. **WiX Toolset v5 기반 단일 설치 패키지(EXE) 및 게시 출력 폴더 정화(Clean) 구축**:
* **안정적인 Wix v5 핀 지정**: 최신 베타 버전인 Wix 7.0 CLI의 Bal 확장 호환 버그를 피하고자, 안정 릴리즈인 **Wix v5.0.2**로 툴을 다운그레이드 핀 지정하고 **Wix Bootstrapper Applications v5.0.2** 확장을 전역 추가했습니다.
* **단일 EXE 설치본 자동 빌드**: `Bundle.wxs`를 작성하여 기존의 MSI 패키지를 내장 압축 래핑하는 **`LeakTestSetup.exe`** 단일 설치 파일을 자동으로 빌드(Ext 인자 전달)하도록 빌드 타겟을 확장했습니다.
* **C드라이브 설치 경로 강제 고정**: 주 드라이브 매핑 설정과 관계없이 항상 약속된 설치 디렉터리(`C:\LeakTest`)에 바이너리 및 설정 파일, 네이티브 DLL 하위 폴더 구조(`libs/`)가 무조건 자동 설치되도록 `Product.wxs` 내에 `SetDirectory` 강제 매핑 및 `perMachine` 스코프를 수립했습니다.
* **바탕화면 바로가기 자동 생성**: 설치 시 공용 바탕화면 경로에 `Leak Test System` 실행 바로가기 단축 아이콘(`.lnk`)이 자동으로 생성되어 작업자의 실행 편의를 극대화했습니다.
* **사전 빌드 복사 에러 조치**: `dotnet publish``PCI-Dask.dll``.config` 파일 복사 경로 문제로 빌드가 실패하던 오류들을 프로젝트 디렉터리 및 빌드 디렉터리 원본을 정확히 바라보도록 수정하여 빌드 무결성을 회피했습니다.
* **게시 폴더 정화 자동화**: 비주얼 스튜디오에서 '게시(Publish)' 완료 시 출력 경로(`PublishDir`) 하위의 수많은 부가 DLL, PDB, Config, Json, Ini 파일 및 서브 폴더들을 완전히 청소(Clean)하여, 오직 최종 배포용 단일 실행 파일인 **`LeakTestSetup.exe` 파일 단 하나만 남도록** 대피/이관 자동화 스크립트를 빌드 타겟에 연동했습니다.
### 📅 2026-07-02 (SQL 연결 SSL 인증서 체인 신뢰성 오류 방지 및 기본 접속 정보 변경)
* **내용**: SQL 접속 시 SSL 인증서 체인 오류를 기본 방지하도록 설정을 개선하고, 시스템 기획 요구사항에 맞춰 기본 데이터베이스 접속 정보를 최신화하였습니다.
* **기능**:
1. **ConnectionString 생성 로직 개선**: [DatabaseSettings.cs](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/DatabaseSettings.cs) 내의 `ConnectionString` 프로퍼티에서 개별 파라미터(Server, Database, User 등)로 조합되거나 단일 설정값으로 주입된 연결 문자열에 `TrustServerCertificate=True;` 옵션이 존재하지 않을 경우 자동으로 접미사에 추가하도록 수정하여 SSL 인증서 관련 연결 예외를 방지했습니다.
2. **Database.ini 기본 템플릿 접속 정보 업데이트**: 프로그램 구동 시 파일이 존재하지 않는 경우 자동 생성하는 디폴트 템플릿([App.xaml.cs](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/App.xaml.cs)) 및 프로젝트에 포함된 기본 [Database.ini](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Database.ini) 설정 파일의 접속 정보(서버: 192.168.10.10, 1433, DB명: NE1aW_PT_SSENSOR, 사용자: su, 비밀번호: amotech821)를 실 시스템 기획 요구사항에 맞춰 갱신하였습니다.
3. **Line 컬럼 잘림 오류 수정**: DB의 [dbo].[EOL] 테이블 스키마 파일([dbo.EOL_Schema.sql](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/DB/dbo.EOL_Schema.sql))에서 작업 라인을 나타내는 `Line` 컬럼의 물리 데이터 형식이 `NVARCHAR(5)`로 좁게 선언되어 있어 5자를 초과하는 라인 정보(예: `"LINE-1"`은 6자) 입력 시 잘림 오류(Truncation Exception)로 인해 저장이 실패하던 버그를 확인하고, 테이블 DDL 스키마 및 문서 상의 `Line` 규격을 `NVARCHAR(30)`로 변경 및 확장 조치하였습니다.
4. **Line 컬럼 가공 처리 원복**: 라인 정보에 대해 숫자만 남기도록 하던 임시 정규식 필터링 코드를 제거하고, 원래 문자열 형태(예: `"LINE-1"`) 그대로 데이터베이스 및 CSV 로그에 기록되도록 소스코드를 복구하였습니다.

11
ob/db_login_integration.md

@ -95,7 +95,7 @@
| `Variant_2` | `NVARCHAR(10)` | 로그인 변형2 정보 (`App.LoginResult.Variant2`) | | | `Variant_2` | `NVARCHAR(10)` | 로그인 변형2 정보 (`App.LoginResult.Variant2`) | |
| `Operator` | `NVARCHAR(10)` | 로그인 검사자 ID (`App.LoginResult.Operator`) | | | `Operator` | `NVARCHAR(10)` | 로그인 검사자 ID (`App.LoginResult.Operator`) | |
| `Production_Date` | `DATETIME2(0)` | 검사 일시 (`inspectData.ProductionDate ?? DateTime.Now`) | | | `Production_Date` | `DATETIME2(0)` | 검사 일시 (`inspectData.ProductionDate ?? DateTime.Now`) | |
| `Line` | `NVARCHAR(5)` | 로그인 작업 라인 (`App.LoginResult.LineNo`) | | | `Line` | `NVARCHAR(30)` | 로그인 작업 라인 (`App.LoginResult.LineNo`) | |
| `Lot_No` | `NVARCHAR(8)` | 로그인 Lot 번호 (`App.LoginResult.LotNo`) | | | `Lot_No` | `NVARCHAR(8)` | 로그인 Lot 번호 (`App.LoginResult.LotNo`) | |
| `Jig_No` | `NVARCHAR(10)` | 로그인 지그 번호 (`App.LoginResult.JigNo`) | | | `Jig_No` | `NVARCHAR(10)` | 로그인 지그 번호 (`App.LoginResult.JigNo`) | |
| `Channel` | `NVARCHAR(5)` | 검증 수행 채널 (`LEFT` / `RIGHT`) | | | `Channel` | `NVARCHAR(5)` | 검증 수행 채널 (`LEFT` / `RIGHT`) | |
@ -139,6 +139,8 @@ WHEN NOT MATCHED THEN
* `decimal.TryParse` 패턴을 도입하여 `SpecUL`, `SpecLL`, `MeasuredValue`와 같은 수치형 데이터를 안전하게 파싱한 뒤 SQL Parameter로 전달함으로써 타입 변환 예외 위험을 격리했습니다. * `decimal.TryParse` 패턴을 도입하여 `SpecUL`, `SpecLL`, `MeasuredValue`와 같은 수치형 데이터를 안전하게 파싱한 뒤 SQL Parameter로 전달함으로써 타입 변환 예외 위험을 격리했습니다.
* **개별 매핑 및 시간 동기화**: `inspectData.IcSn``inspectData.PcbBarcode`를 DB 파라미터로 각각 매핑하고, 저장 시간 역시 CSV와의 정합성 일치를 위해 `inspectData.ProductionDate ?? DateTime.Now`를 바인딩하도록 고도화했습니다. * **개별 매핑 및 시간 동기화**: `inspectData.IcSn``inspectData.PcbBarcode`를 DB 파라미터로 각각 매핑하고, 저장 시간 역시 CSV와의 정합성 일치를 위해 `inspectData.ProductionDate ?? DateTime.Now`를 바인딩하도록 고도화했습니다.
* **연결 제한 시간 설정**: 네트워크 불안정 등으로 저장 실패 시 오래 대기하지 않도록 `SqlConnectionStringBuilder`를 사용하여 연결 제한 시간(`ConnectTimeout`)을 **1초**로 명시적 지정하였습니다. * **연결 제한 시간 설정**: 네트워크 불안정 등으로 저장 실패 시 오래 대기하지 않도록 `SqlConnectionStringBuilder`를 사용하여 연결 제한 시간(`ConnectTimeout`)을 **1초**로 명시적 지정하였습니다.
* **[DatabaseSettings.cs](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/DatabaseSettings.cs)**:
* **SSL 인증서 체인 신뢰성 오류 대응**: 데이터베이스 접속 설정(`Database.ini`)을 파싱하여 조합된 커넥션 스트링을 생성할 때, 신뢰되지 않은 인증서 오류(TrustServerCertificate 누락으로 인한 SSL 공급자 에러 0)를 원천 차단하기 위해 `TrustServerCertificate=True;` 옵션이 존재하지 않을 경우 자동으로 연결 문자열 접미사에 추가하도록 `ConnectionString` 프로퍼티 get 로직을 개선했습니다.
* **[TestProcessService.cs (EolDatabaseService 인스턴스 생성)](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/TestProcessService.cs)**: * **[TestProcessService.cs (EolDatabaseService 인스턴스 생성)](file:///c:/Users/COMPUTER1/Desktop/mobi/leak_test_project/leak_test_project/Services/TestProcessService.cs)**:
* 기존에 분산 관리되던 DB 접속 스트링(`config.xml`의 `DbConnectionString`) 대신, 모든 데이터베이스 접속 및 검증 주소를 `Database.ini` 파일 하나로 일원화하기 위해 `DatabaseSettings.Load(dbIniPath).ConnectionString` 방식으로 접속 정보를 읽어오도록 수정하여 설정 관리 포인트를 통합했습니다. * 기존에 분산 관리되던 DB 접속 스트링(`config.xml`의 `DbConnectionString`) 대신, 모든 데이터베이스 접속 및 검증 주소를 `Database.ini` 파일 하나로 일원화하기 위해 `DatabaseSettings.Load(dbIniPath).ConnectionString` 방식으로 접속 정보를 읽어오도록 수정하여 설정 관리 포인트를 통합했습니다.
* **메타데이터 저장 정합성 확보**: 합격, 불합격, 타임아웃 등 모든 분기에서 `InspectData` 객체 생성 시 로그인 정보(`Maker`, `Model`, `Variant`, `Operator` 등) 및 실제 검사 시간(`ProductionDate`), 바코드 값을 완벽히 주입하여 로컬 CSV 백업 파일 작성 시 공란으로 비어있지 않도록 일원화했습니다. * **메타데이터 저장 정합성 확보**: 합격, 불합격, 타임아웃 등 모든 분기에서 `InspectData` 객체 생성 시 로그인 정보(`Maker`, `Model`, `Variant`, `Operator` 등) 및 실제 검사 시간(`ProductionDate`), 바코드 값을 완벽히 주입하여 로컬 CSV 백업 파일 작성 시 공란으로 비어있지 않도록 일원화했습니다.
@ -174,10 +176,11 @@ WHEN NOT MATCHED THEN
2. **오프라인 미리보기 모드(OfflinePreview)**: `OfflinePreview` 설정이 `true`로 활성화되어 있을 경우, 실제 데이터베이스 연결을 생략하고 지정된 테스트 바코드 상수값인 **`"testPCBbarcode"`**를 `PCB_Barcode` 데이터로 주입하여 시험을 정상적으로 이어나갑니다. 2. **오프라인 미리보기 모드(OfflinePreview)**: `OfflinePreview` 설정이 `true`로 활성화되어 있을 경우, 실제 데이터베이스 연결을 생략하고 지정된 테스트 바코드 상수값인 **`"testPCBbarcode"`**를 `PCB_Barcode` 데이터로 주입하여 시험을 정상적으로 이어나갑니다.
3. **조회 예외 및 데이터 누락 대응**: DB 통신 장애로 인한 예외(SqlException 등)가 발생하거나 매핑 정보가 존재하지 않을 경우, 즉시 화면에 `"바코드 매핑 실패: [ExceptionType] ExceptionMessage"` 또는 `"바코드 매핑 실패: 매핑 데이터 없음"` 오류를 출력하고 기밀 시험을 즉각 중단합니다. 3. **조회 예외 및 데이터 누락 대응**: DB 통신 장애로 인한 예외(SqlException 등)가 발생하거나 매핑 정보가 존재하지 않을 경우, 즉시 화면에 `"바코드 매핑 실패: [ExceptionType] ExceptionMessage"` 또는 `"바코드 매핑 실패: 매핑 데이터 없음"` 오류를 출력하고 기밀 시험을 즉각 중단합니다.
4. **물리 출력 및 정합성 보장**: 조회가 실패하여 중단된 장치는 물리 NG 접점(`side_NG`)을 출력 처리하고, `TestCompleted` 이벤트 및 CSV 결과 로그에 `PcbBarcode = "-"` 및 판정 결과 `NG`를 이중 기록하여 무결성을 유지합니다. 4. **물리 출력 및 정합성 보장**: 조회가 실패하여 중단된 장치는 물리 NG 접점(`side_NG`)을 출력 처리하고, `TestCompleted` 이벤트 및 CSV 결과 로그에 `PcbBarcode = "-"` 및 판정 결과 `NG`를 이중 기록하여 무결성을 유지합니다.
5. **메인 화면 식별자 행 분리 및 마진 최적화**: 좌/우 채널 모니터링 테이블 내부의 식별자 정보를 가로 텍스트 잘림 현상 예방 및 가독성 강화를 위해 기존 `"ID"` 행에서 **`"IC_SN"`**과 **`"PCB_Barcode"`**의 **2개 독립된 행(Rows)으로 분할**하여 전면 배치했습니다. 이를 통해 고정 헤더 가로폭을 확장하지 않고 기존의 깔끔한 가로 너비인 **`130`**을 안정적으로 유지합니다. 더불어 영문 `"PCB_Barcode"` 라벨 텍스트의 좌우 여백을 개별 마진 **`Margin="6,0"`**으로 미세 조율하여, 윈도우의 가로 크기를 최소 사양인 **`1150`**으로 줄인 창모드 상태에서도 단 1픽셀의 잘림 없이 모든 텍스트가 명확하게 표현되도록 방어했습니다. 5. **ID 판독 실패 시 안전 제어 및 크래시 방지**: 시험 기동 신호 유입 시 ID 센서로부터 ID 값(IC_SN)을 판독하는 데 실패한 경우(`sensorData == null`), 즉시 화면에 `"ID 읽기 실패"` 오류를 출력하고 물리 NG 접점(`side_NG`)을 출력 및 결과 이벤트를 전송한 후, `continue` 제어문을 통해 시험 시퀀스를 즉각 중단하고 다음 시험 대기 상태로 복귀하도록 구현하여 `NullReferenceException`에 의한 프로그램 비정상 종료(크래시) 현상을 완벽히 방지하였습니다.
6. **설정 파일 통합 및 C드라이브 배포 자동화**: 6. **메인 화면 식별자 행 분리 및 마진 최적화**: 좌/우 채널 모니터링 테이블 내부의 식별자 정보를 가로 텍스트 잘림 현상 예방 및 가독성 강화를 위해 기존 `"ID"` 행에서 **`"IC_SN"`**과 **`"PCB_Barcode"`**의 **2개 독립된 행(Rows)으로 분할**하여 전면 배치했습니다. 이를 통해 고정 헤더 가로폭을 확장하지 않고 기존의 깔끔한 가로 너비인 **`130`**을 안정적으로 유지합니다. 더불어 영문 `"PCB_Barcode"` 라벨 텍스트의 좌우 여백을 개별 마진 **`Margin="6,0"`**으로 미세 조율하여, 윈도우의 가로 크기를 최소 사양인 **`1150`**으로 줄인 창모드 상태에서도 단 1픽셀의 잘림 없이 모든 텍스트가 명확하게 표현되도록 방어했습니다.
7. **설정 파일 통합 및 C드라이브 배포 자동화**:
* **설정 통합**: 클릭원스 배포 시 설정 파편화를 방지하기 위해 로컬 로그인 설정 파일(`LoginOptions.json`) 및 로그인 내역 파일(`LoginHistory.json`)의 생성 및 조회 경로를 `Database.ini`와 동일한 공용 경로인 **`C:\ProgramData\LeakTest\`**로 일원화하였습니다. * **설정 통합**: 클릭원스 배포 시 설정 파편화를 방지하기 위해 로컬 로그인 설정 파일(`LoginOptions.json`) 및 로그인 내역 파일(`LoginHistory.json`)의 생성 및 조회 경로를 `Database.ini`와 동일한 공용 경로인 **`C:\ProgramData\LeakTest\`**로 일원화하였습니다.
* **C드라이브 설치 자동화**: `ClickOnceProfile.pubxml`의 게시 경로(`PublishUrl`)를 **`C:\LeakTest\`**로 수정하고, `leak_test_project.csproj` 파일 내에 `PostPublishCopy` MSBuild Target을 연동하여 퍼블리시 성공 시 배포 실행 패키지 파일들이 C드라이브 대상 경로(`C:\LeakTest\`)로 자동 생성 및 복제되도록 구축하였습니다. * **C드라이브 설치 자동화**: `ClickOnceProfile.pubxml`의 게시 경로(`PublishUrl`)를 **`C:\LeakTest\**로 수정하고, `leak_test_project.csproj` 파일 내에 `PostPublishCopy` MSBuild Target을 연동하여 퍼블리시 성공 시 배포 실행 패키지 파일들이 C드라이브 대상 경로(`C:\LeakTest\`)로 자동 생성 및 복제되도록 구축하였습니다.
--- ---

Loading…
Cancel
Save