diff --git a/MainWindow.xaml b/MainWindow.xaml
index 44a20ef..5e1ebba 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -153,6 +153,23 @@
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 19d130c..2fc80dc 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -20,20 +20,40 @@ namespace DwgExtractorManual
private DispatcherTimer _timer;
private ExportExcel? _exportExcel;
private SqlDatas? _sqlDatas;
+ // μλ μ²λ¦¬ λͺ¨λ νλκ·Έ
+ private bool isAutoProcessing = false;
public MainWindow()
{
InitializeComponent();
InitializeDefaultPaths();
InitializeTimer();
+
+ // μ± μ’
λ£ μ Teigha 리μμ€ μ 리
+ this.Closed += MainWindow_Closed;
+
LogMessage("π DWG μ 보 μΆμΆκΈ°κ° μμλμμ΅λλ€.");
}
+ private void MainWindow_Closed(object sender, EventArgs e)
+ {
+ try
+ {
+ LogMessage("π μ ν리μΌμ΄μ
μ’
λ£ μ Teigha 리μμ€ μ 리 μ€...");
+ TeighaServicesManager.Instance.ForceDisposeServices();
+ LogMessage("β
Teigha 리μμ€ μ 리 μλ£");
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β οΈ μ± μ’
λ£ μ Teigha μ 리 μ€ μ€λ₯: {ex.Message}");
+ }
+ }
+
private void InitializeDefaultPaths()
{
// κΈ°λ³Έ κ²½λ‘ μ€μ - μ€μ νκ²½μ λ§κ² μμ
- txtSourceFolder.Text = @"D:\dwgpdfcompare\test2";
- txtResultFolder.Text = @"D:\dwgpdfcompare\result";
+ txtSourceFolder.Text = @"C:\WorkProjects\dwfpdfCompare";
+ txtResultFolder.Text = @"C:\WorkProjects\dwfpdfCompare";
// κ²½λ‘κ° μ‘΄μ¬νμ§ μμΌλ©΄ κΈ°λ³Έκ°μΌλ‘ μ€μ
if (!Directory.Exists(txtSourceFolder.Text))
@@ -157,17 +177,15 @@ namespace DwgExtractorManual
private async void BtnExtract_Click(object sender, RoutedEventArgs e)
{
// μ
λ ₯ μ ν¨μ± κ²μ¬
- if (string.IsNullOrEmpty(txtSourceFolder.Text) || !Directory.Exists(txtSourceFolder.Text))
+ if (string.IsNullOrEmpty(txtSourceFolder.Text) || !Directory.Exists(txtSourceFolder.Text))
{
- System.Windows.MessageBox.Show("μ ν¨ν λ³νν ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯",
- MessageBoxButton.OK, MessageBoxImage.Warning);
+ ShowMessageBox("μ ν¨ν λ³νν ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
-
+
if (string.IsNullOrEmpty(txtResultFolder.Text) || !Directory.Exists(txtResultFolder.Text))
{
- System.Windows.MessageBox.Show("μ ν¨ν κ²°κ³Ό μ μ₯ ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯",
- MessageBoxButton.OK, MessageBoxImage.Warning);
+ ShowMessageBox("μ ν¨ν κ²°κ³Ό μ μ₯ ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
@@ -181,11 +199,11 @@ namespace DwgExtractorManual
{
if (!testSql.TestConnection())
{
- System.Windows.MessageBox.Show(
- "PostgreSQL λ°μ΄ν°λ² μ΄μ€μ μ°κ²°ν μ μμ΅λλ€.\n\n" +
- "μ°κ²° μ€μ μ νμΈνκ³ λ°μ΄ν°λ² μ΄μ€ μλ²κ° μ€ν μ€μΈμ§ νμΈνμΈμ.",
- "λ°μ΄ν°λ² μ΄μ€ μ°κ²° μ€λ₯",
- MessageBoxButton.OK, MessageBoxImage.Error);
+ ShowMessageBox(
+ "PostgreSQL λ°μ΄ν°λ² μ΄μ€μ μ°κ²°ν μ μμ΅λλ€.\n\n" +
+ "μ°κ²° μ€μ μ νμΈνκ³ λ°μ΄ν°λ² μ΄μ€ μλ²κ° μ€ν μ€μΈμ§ νμΈνμΈμ.",
+ "λ°μ΄ν°λ² μ΄μ€ μ°κ²° μ€λ₯",
+ MessageBoxButton.OK, MessageBoxImage.Error);
LogMessage("β λ°μ΄ν°λ² μ΄μ€ μ°κ²° μ€ν¨");
return;
}
@@ -194,7 +212,7 @@ namespace DwgExtractorManual
}
catch (Exception ex)
{
- System.Windows.MessageBox.Show(
+ ShowMessageBox(
$"λ°μ΄ν°λ² μ΄μ€ μ°κ²° ν
μ€νΈ μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n\n{ex.Message}",
"μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
LogMessage($"β λ°μ΄ν°λ² μ΄μ€ μ°κ²° μ€λ₯: {ex.Message}");
@@ -206,6 +224,7 @@ namespace DwgExtractorManual
btnExtract.IsEnabled = false;
btnPdfExtract.IsEnabled = false;
btnMerge.IsEnabled = false;
+ btnAuto.IsEnabled = false;
btnBrowseSource.IsEnabled = false;
btnBrowseResult.IsEnabled = false;
rbExcel.IsEnabled = false;
@@ -225,8 +244,7 @@ namespace DwgExtractorManual
{
LogMessage($"β μΉλͺ
μ μ€λ₯ λ°μ: {ex.Message}");
UpdateStatus("μ€λ₯κ° λ°μνμ΅λλ€.");
- System.Windows.MessageBox.Show($"μμ
μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n\n{ex.Message}",
- "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ ShowMessageBox($"μμ
μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n\n{ex.Message}", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
@@ -234,6 +252,7 @@ namespace DwgExtractorManual
btnExtract.IsEnabled = true;
btnPdfExtract.IsEnabled = true;
btnMerge.IsEnabled = true;
+ btnAuto.IsEnabled = true;
btnBrowseSource.IsEnabled = true;
btnBrowseResult.IsEnabled = true;
rbExcel.IsChecked = true;
@@ -242,9 +261,280 @@ namespace DwgExtractorManual
LogMessage(new string('=', 50));
LogMessage("π μμ
μλ£");
LogMessage(new string('=', 50)); // β
μ μ μλ
+
+ // μλ μ²λ¦¬ λͺ¨λ λΉνμ±ν
+ isAutoProcessing = false;
}
}
+ ///
+ /// MessageBox νμ (μλ λͺ¨λμμλ λ‘κ·Έλ§ μΆλ ₯)
+ ///
+ private void ShowMessageBox(string message, string title, MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage image = MessageBoxImage.Information)
+ {
+ if (isAutoProcessing)
+ {
+ LogMessage($"π’ {title}: {message}");
+ }
+ else
+ {
+ System.Windows.MessageBox.Show(message, title, button, image);
+ }
+ }
+
+ ///
+ /// νμΈ λνμμ νμ (μλ λͺ¨λμμλ μλμΌλ‘ Yes λ°ν)
+ ///
+ private MessageBoxResult ShowConfirmationDialog(string message, string title)
+ {
+ if (isAutoProcessing)
+ {
+ LogMessage($"π’ {title}: {message} - μλ μΉμΈλ¨");
+ return MessageBoxResult.Yes;
+ }
+ else
+ {
+ return System.Windows.MessageBox.Show(message, title, MessageBoxButton.YesNo, MessageBoxImage.Question);
+ }
+ }
+
+ ///
+ /// DWG νμΌ μ²λ¦¬ - μλ λͺ¨λμ© (ν΄λ κ²½λ‘ μ§μ μ§μ )
+ ///
+ /// μ²λ¦¬ν ν΄λ κ²½λ‘
+ private async Task ProcessFiles(string sourceFolderPath)
+ {
+ var stopwatch = Stopwatch.StartNew();
+ var targetDir = new DirectoryInfo(sourceFolderPath);
+ var files = targetDir.GetFiles("*.dwg", SearchOption.AllDirectories);
+
+ if (files.Length == 0)
+ {
+ UpdateStatus("μ νν ν΄λμ DWG νμΌμ΄ μμ΅λλ€.");
+ ShowMessageBox("μ νν ν΄λμ DWG νμΌμ΄ μμ΅λλ€.", "μ 보", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ // κ²°κ³Ό μ μ₯ ν΄λλ UIμμ κ°μ Έμ΄ (λ³κ²½νμ§ μμ)
+ string resultDir = txtResultFolder.Text;
+
+ LogMessage($"π μ²λ¦¬ν νμΌ μ: {files.Length}κ°");
+ LogMessage($"π μΆλ ₯ λͺ¨λ: {(rbExcel.IsChecked == true ? "Excel" : "Database")}");
+ LogMessage($"π μμ€ ν΄λ: {sourceFolderPath}");
+ LogMessage($"πΎ κ²°κ³Ό ν΄λ: {resultDir}");
+
+ try
+ {
+ if (rbExcel.IsChecked == true)
+ {
+ LogMessage("π Excel λ΄λ³΄λ΄κΈ° λͺ¨λλ‘ μμν©λλ€...");
+
+ ExportExcel? _exportExcel = null;
+ var successCount = 0;
+ var failureCount = 0;
+ var totalProcessingTime = 0.0;
+
+ try
+ {
+ _exportExcel = new ExportExcel();
+ LogMessage("π Excel μ ν리μΌμ΄μ
μ΄κΈ°ν μ€...");
+ LogMessage("β
Excel μ ν리μΌμ΄μ
μ΄κΈ°ν μλ£");
+
+ for (int i = 0; i < files.Length; i++)
+ {
+ var file = files[i];
+ var fileStopwatch = Stopwatch.StartNew();
+
+ UpdateStatus($"μ²λ¦¬ μ€: {file.Name} ({i + 1}/{files.Length})");
+ LogMessage($"π [{i + 1}/{files.Length}] μ²λ¦¬ μ€: {file.Name}");
+
+ try
+ {
+ // μ€μ DWG μ²λ¦¬ λ‘μ§
+ var progress = new Progress(value =>
+ {
+ // νμΌλ³ μ§νλ₯ μ μ 체 μ§νλ₯ μ λ°μ
+ var overallProgress = ((i * 100.0 + value) / files.Length);
+ progressBar.Value = overallProgress;
+ });
+
+ bool success = _exportExcel.ExportDwgToExcel(file.FullName, progress);
+
+ fileStopwatch.Stop();
+
+ if (success)
+ {
+ successCount++;
+ totalProcessingTime += fileStopwatch.ElapsedMilliseconds;
+ LogMessage($"β
{file.Name} μ²λ¦¬ μλ£ ({fileStopwatch.ElapsedMilliseconds}ms)");
+ }
+ else
+ {
+ failureCount++;
+ LogMessage($"β {file.Name} μ²λ¦¬ μ€ν¨ ({fileStopwatch.ElapsedMilliseconds}ms)");
+ }
+ }
+ catch (Exception ex)
+ {
+ failureCount++;
+ fileStopwatch.Stop();
+ LogMessage($"π₯ {file.Name} μ²λ¦¬ μ€ μμΈ λ°μ: {ex.Message}");
+ }
+
+ // μ§νλ₯ μ
λ°μ΄νΈ
+ progressBar.Value = ((i + 1) * 100.0) / files.Length;
+
+ // UI μλ΅μ±μ μν μ§§μ μ§μ°
+ await Task.Delay(10);
+ }
+
+ // Excel νμΌ λ° λ§€ν λ°μ΄ν° μ μ₯
+ var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
+ var excelFileName = Path.Combine(resultDir, $"{timestamp}_DwgToExcel.xlsx");
+ var mappingDataFile = Path.Combine(resultDir, $"{timestamp}_mapping_data.json");
+
+ LogMessage("πΎ Excel νμΌκ³Ό λ§€ν λ°μ΄ν°λ₯Ό μ μ₯ν©λλ€...");
+
+ // λ§€ν λμ
λ리λ₯Ό JSON νμΌλ‘ μ μ₯ (PDF λ°μ΄ν° λ³ν©μ©)
+ _exportExcel.SaveMappingDictionary(mappingDataFile);
+ LogMessage($"β
λ§€ν λ°μ΄ν° μ μ₯ μλ£: {Path.GetFileName(mappingDataFile)}");
+
+ // Excel νμΌ μ μ₯
+ _exportExcel.SaveAndCloseExcel(excelFileName);
+ LogMessage($"β
Excel νμΌ μ μ₯ μλ£: {Path.GetFileName(excelFileName)}");
+
+ var elapsed = stopwatch.Elapsed;
+ LogMessage($"β
Excel λ΄λ³΄λ΄κΈ° μλ£! μμμκ°: {elapsed.TotalSeconds:F1}μ΄");
+ UpdateStatus($"β
{files.Length}κ° νμΌ μ²λ¦¬ μλ£");
+ LogMessage($"π μ±κ³΅: {successCount}κ°, μ€ν¨: {failureCount}κ°");
+ LogMessage($"β±οΈ νκ· μ²λ¦¬ μκ°: {(successCount > 0 ? totalProcessingTime / successCount : 0):F1}ms");
+
+ if (!isAutoProcessing)
+ {
+ ShowMessageBox($"Excel λ΄λ³΄λ΄κΈ°κ° μλ£λμμ΅λλ€!\n\n" +
+ $"β
μ±κ³΅: {successCount}κ°\n" +
+ $"β μ€ν¨: {failureCount}κ°\n" +
+ $"β±οΈ μ΄ μμμκ°: {elapsed:mm\\:ss}\n\n" +
+ $"π κ²°κ³Ό νμΌμ΄ μ μ₯ ν΄λμ μμ±λμμ΅λλ€.",
+ "μλ£", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β Excel μ²λ¦¬ μ€ μΉλͺ
μ μ€λ₯: {ex.Message}");
+ UpdateStatus("β Excel μ²λ¦¬ μ€ν¨");
+ if (!isAutoProcessing)
+ {
+ ShowMessageBox("Excel μ²λ¦¬ μ€ μ€λ₯κ° λ°μνμ΅λλ€. λ‘κ·Έλ₯Ό νμΈν΄μ£ΌμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ throw;
+ }
+ finally
+ {
+ _exportExcel?.Dispose();
+ _exportExcel = null;
+ }
+ }
+ else if (rbDatabase.IsChecked == true)
+ {
+ LogMessage("ποΈ λ°μ΄ν°λ² μ΄μ€ λͺ¨λλ‘ μμν©λλ€...");
+ LogMessage("π λ°μ΄ν°λ² μ΄μ€ μ°κ²°μ μ΄κΈ°νν©λλ€...");
+
+ SqlDatas? _sqlDatas = null;
+ var successCount = 0;
+ var failureCount = 0;
+ var totalProcessingTime = 0.0;
+
+ try
+ {
+ _sqlDatas = new SqlDatas();
+ LogMessage("β
λ°μ΄ν°λ² μ΄μ€ μ°κ²° μ΄κΈ°ν μλ£");
+
+ for (int i = 0; i < files.Length; i++)
+ {
+ var file = files[i];
+ var fileStopwatch = Stopwatch.StartNew();
+
+ UpdateStatus($"μ²λ¦¬ μ€: {file.Name} ({i + 1}/{files.Length})");
+ LogMessage($"π [{i + 1}/{files.Length}] μ²λ¦¬ μ€: {file.Name}");
+
+ try
+ {
+ // μ€μ DWG μ²λ¦¬ λ‘μ§ (DwgToDBλ μ€ν¨μ true λ°ν)
+ bool failed = _sqlDatas.DwgToDB(file.FullName);
+ bool success = !failed;
+
+ fileStopwatch.Stop();
+
+ if (success)
+ {
+ successCount++;
+ totalProcessingTime += fileStopwatch.ElapsedMilliseconds;
+ LogMessage($"β
{file.Name} DB μ μ₯ μλ£ ({fileStopwatch.ElapsedMilliseconds}ms)");
+ }
+ else
+ {
+ failureCount++;
+ LogMessage($"β {file.Name} DB μ μ₯ μ€ν¨ ({fileStopwatch.ElapsedMilliseconds}ms)");
+ }
+ }
+ catch (Exception ex)
+ {
+ failureCount++;
+ fileStopwatch.Stop();
+ LogMessage($"π₯ {file.Name} μ²λ¦¬ μ€ μμΈ λ°μ: {ex.Message}");
+ }
+
+ // μ§νλ₯ μ
λ°μ΄νΈ
+ progressBar.Value = ((i + 1) * 100.0) / files.Length;
+
+ // UI μλ΅μ±μ μν μ§§μ μ§μ°
+ await Task.Delay(10);
+ }
+
+ var elapsed = stopwatch.Elapsed;
+ LogMessage($"β
λ°μ΄ν°λ² μ΄μ€ μ μ₯ μλ£! μμμκ°: {elapsed.TotalSeconds:F1}μ΄");
+ UpdateStatus($"β
{files.Length}κ° νμΌ μ²λ¦¬ μλ£");
+ LogMessage($"π μ±κ³΅: {successCount}κ°, μ€ν¨: {failureCount}κ°");
+ LogMessage($"β±οΈ νκ· μ²λ¦¬ μκ°: {(successCount > 0 ? totalProcessingTime / successCount : 0):F1}ms");
+
+ if (!isAutoProcessing)
+ {
+ ShowMessageBox($"λ°μ΄ν°λ² μ΄μ€ μ μ₯μ΄ μλ£λμμ΅λλ€!\n\n" +
+ $"β
μ±κ³΅: {successCount}κ°\n" +
+ $"β μ€ν¨: {failureCount}κ°\n" +
+ $"β±οΈ μ΄ μμμκ°: {elapsed:mm\\:ss}",
+ "μλ£", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β λ°μ΄ν°λ² μ΄μ€ μ²λ¦¬ μ€ μΉλͺ
μ μ€λ₯: {ex.Message}");
+ UpdateStatus("β λ°μ΄ν°λ² μ΄μ€ μ²λ¦¬ μ€ν¨");
+ if (!isAutoProcessing)
+ {
+ ShowMessageBox("λ°μ΄ν°λ² μ΄μ€ μ²λ¦¬ μ€ μ€λ₯κ° λ°μνμ΅λλ€. λ‘κ·Έλ₯Ό νμΈν΄μ£ΌμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ throw;
+ }
+ finally
+ {
+ _sqlDatas?.Dispose();
+ _sqlDatas = null;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β μ²λ¦¬ μ€ μ€λ₯ λ°μ: {ex.Message}");
+ UpdateStatus("β μ²λ¦¬ μ€ν¨");
+ throw;
+ }
+ }
+
+ ///
+ /// DWG νμΌ μ²λ¦¬ - κΈ°μ‘΄ λ©μλ
+ ///
private async Task ProcessFiles()
{
var stopwatch = Stopwatch.StartNew();
@@ -254,8 +544,7 @@ namespace DwgExtractorManual
if (files.Length == 0)
{
UpdateStatus("μ νν ν΄λμ DWG νμΌμ΄ μμ΅λλ€.");
- System.Windows.MessageBox.Show("μ νν ν΄λμ DWG νμΌμ΄ μμ΅λλ€.",
- "μ 보", MessageBoxButton.OK, MessageBoxImage.Information);
+ ShowMessageBox("μ νν ν΄λμ DWG νμΌμ΄ μμ΅λλ€.", "μ 보", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
@@ -356,6 +645,22 @@ namespace DwgExtractorManual
// Excel νμΌ μ μ₯
_exportExcel.SaveAndCloseExcel(excelFileName);
LogMessage($"β
Excel νμΌ μ μ₯ μλ£: {Path.GetFileName(excelFileName)}");
+
+
+ LogMessage($"β
Excel λ΄λ³΄λ΄κΈ° μλ£!");
+ UpdateStatus($"β
{files.Length}κ° νμΌ μ²λ¦¬ μλ£");
+ LogMessage($"π μ±κ³΅: {successCount}κ°, μ€ν¨: {failureCount}κ°");
+ LogMessage($"β±οΈ νκ· μ²λ¦¬ μκ°: {(successCount > 0 ? totalProcessingTime / successCount : 0):F1}ms");
+
+ if (!isAutoProcessing)
+ {
+ ShowMessageBox($"Excel λ΄λ³΄λ΄κΈ°κ° μλ£λμμ΅λλ€!\n\n" +
+ $"β
μ±κ³΅: {successCount}κ°\n" +
+ $"β μ€ν¨: {failureCount}κ°\n" +
+ $"β
Excel λ΄λ³΄λ΄κΈ° μλ£!" +
+ $"π κ²°κ³Ό νμΌμ΄ μ μ₯ ν΄λμ μμ±λμμ΅λλ€.",
+ "μλ£", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
}
catch (Exception ex)
{
@@ -376,7 +681,7 @@ namespace DwgExtractorManual
LogMessage($"β±οΈ νκ· μ²λ¦¬ μκ°: {(successCount > 0 ? totalProcessingTime / successCount : 0):F1}ms");
LogMessage($"π μ΄ μμ μκ°: {totalStopwatch.ElapsedMilliseconds}ms");
- System.Windows.MessageBox.Show(
+ ShowMessageBox(
$"Excel λ΄λ³΄λ΄κΈ°κ° μλ£λμμ΅λλ€!\n\n" +
$"β
μ±κ³΅: {successCount}κ°\n" +
$"β μ€ν¨: {failureCount}κ°\n" +
@@ -461,7 +766,7 @@ namespace DwgExtractorManual
LogMessage($"β±οΈ νκ· μ²λ¦¬ μκ°: {(successCount > 0 ? totalProcessingTime / successCount : 0):F1}ms");
LogMessage($"π μ΄ μμ μκ°: {totalStopwatch.ElapsedMilliseconds}ms");
- System.Windows.MessageBox.Show(
+ ShowMessageBox(
$"λ°μ΄ν°λ² μ΄μ€ λ΄λ³΄λ΄κΈ°κ° μλ£λμμ΅λλ€!\n\n" +
$"β
μ±κ³΅: {successCount}κ°\n" +
$"β μ€ν¨: {failureCount}κ°\n" +
@@ -475,15 +780,13 @@ namespace DwgExtractorManual
// μ
λ ₯ μ ν¨μ± κ²μ¬
if (string.IsNullOrEmpty(txtSourceFolder.Text) || !Directory.Exists(txtSourceFolder.Text))
{
- System.Windows.MessageBox.Show("μ ν¨ν λ³νν ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯",
- MessageBoxButton.OK, MessageBoxImage.Warning);
+ ShowMessageBox("μ ν¨ν λ³νν ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (string.IsNullOrEmpty(txtResultFolder.Text) || !Directory.Exists(txtResultFolder.Text))
{
- System.Windows.MessageBox.Show("μ ν¨ν κ²°κ³Ό μ μ₯ ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯",
- MessageBoxButton.OK, MessageBoxImage.Warning);
+ ShowMessageBox("μ ν¨ν κ²°κ³Ό μ μ₯ ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
@@ -493,8 +796,7 @@ namespace DwgExtractorManual
if (pdfFiles.Length == 0)
{
- System.Windows.MessageBox.Show("μ νν ν΄λμ PDF νμΌμ΄ μμ΅λλ€.", "μ 보",
- MessageBoxButton.OK, MessageBoxImage.Information);
+ ShowMessageBox("μ νν ν΄λμ PDF νμΌμ΄ μμ΅λλ€.", "μ 보", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
@@ -502,6 +804,7 @@ namespace DwgExtractorManual
btnExtract.IsEnabled = false;
btnPdfExtract.IsEnabled = false;
btnMerge.IsEnabled = false;
+ btnAuto.IsEnabled = false;
btnBrowseSource.IsEnabled = false;
btnBrowseResult.IsEnabled = false;
rbExcel.IsEnabled = false;
@@ -521,8 +824,7 @@ namespace DwgExtractorManual
{
LogMessage($"β PDF μΆμΆ μ€ μΉλͺ
μ μ€λ₯ λ°μ: {ex.Message}");
UpdateStatus("PDF μΆμΆ μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
- System.Windows.MessageBox.Show($"PDF μΆμΆ μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n\n{ex.Message}",
- "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ ShowMessageBox($"PDF μΆμΆ μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n\n{ex.Message}", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
@@ -530,6 +832,7 @@ namespace DwgExtractorManual
btnExtract.IsEnabled = true;
btnPdfExtract.IsEnabled = true;
btnMerge.IsEnabled = true;
+ btnAuto.IsEnabled = true;
btnBrowseSource.IsEnabled = true;
btnBrowseResult.IsEnabled = true;
rbExcel.IsEnabled = true;
@@ -579,7 +882,7 @@ namespace DwgExtractorManual
$"--include-errors {includeErrors.ToString().ToLower()} " +
$"--output \"{outputPath}\"";
- LogMessage($"π Python μ€ν¬λ¦½νΈ μ€ν μ€λΉ...");
+ LogMessage("π Python μ€ν¬λ¦½νΈ μ€ν μ€λΉ...");
LogMessage($"π Python κ²½λ‘: {pythonPath}");
LogMessage($"π μ€ν¬λ¦½νΈ κ²½λ‘: {scriptPath}");
LogMessage($"π νμΌ λ¦¬μ€νΈ: {Path.GetFileName(tempFileList)}");
@@ -648,7 +951,7 @@ namespace DwgExtractorManual
// μλ Excel λ§€ν μ
λ°μ΄νΈ (μλ‘μ΄ ν¨μ¨μ λ°©μ)
await AutoUpdateExcelMappingWithPdfResults(outputPath);
- System.Windows.MessageBox.Show(
+ ShowMessageBox(
$"PDF μΆμΆμ΄ μλ£λμμ΅λλ€!\n\n" +
$"π μ²λ¦¬λ νμΌ: {pdfFiles.Length}κ°\n" +
$"β±οΈ μ΄ μμμκ°: {stopwatch.Elapsed:mm\\:ss}\n\n" +
@@ -996,8 +1299,7 @@ namespace DwgExtractorManual
// μ
λ ₯ μ ν¨μ± κ²μ¬
if (string.IsNullOrEmpty(txtResultFolder.Text) || !Directory.Exists(txtResultFolder.Text))
{
- System.Windows.MessageBox.Show("μ ν¨ν κ²°κ³Ό μ μ₯ ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯",
- MessageBoxButton.OK, MessageBoxImage.Warning);
+ ShowMessageBox("μ ν¨ν κ²°κ³Ό μ μ₯ ν΄λλ₯Ό μ ννμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
@@ -1005,6 +1307,7 @@ namespace DwgExtractorManual
btnExtract.IsEnabled = false;
btnPdfExtract.IsEnabled = false;
btnMerge.IsEnabled = false;
+ btnAuto.IsEnabled = false;
btnBrowseSource.IsEnabled = false;
btnBrowseResult.IsEnabled = false;
rbExcel.IsEnabled = false;
@@ -1024,8 +1327,7 @@ namespace DwgExtractorManual
{
LogMessage($"β λ§€ν λ³ν© μ€ μΉλͺ
μ μ€λ₯ λ°μ: {ex.Message}");
UpdateStatus("λ§€ν λ³ν© μ€ μ€λ₯κ° λ°μνμ΅λλ€.");
- System.Windows.MessageBox.Show($"λ§€ν λ³ν© μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n\n{ex.Message}",
- "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ ShowMessageBox($"λ§€ν λ³ν© μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n\n{ex.Message}", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
@@ -1033,6 +1335,7 @@ namespace DwgExtractorManual
btnExtract.IsEnabled = true;
btnPdfExtract.IsEnabled = true;
btnMerge.IsEnabled = true;
+ btnAuto.IsEnabled = true;
btnBrowseSource.IsEnabled = true;
btnBrowseResult.IsEnabled = true;
rbExcel.IsEnabled = true;
@@ -1065,7 +1368,7 @@ namespace DwgExtractorManual
LogMessage("β PDF μΆμΆ JSON νμΌμ μ°Ύμ μ μμ΅λλ€.");
LogMessage("π‘ λ¨Όμ 'PDF μΆμΆ' λ²νΌμ μ€ννμ¬ JSON νμΌμ μμ±νμΈμ.");
- System.Windows.MessageBox.Show(
+ ShowMessageBox(
"PDF μΆμΆ JSON νμΌμ μ°Ύμ μ μμ΅λλ€.\n\n" +
"λ¨Όμ 'PDF μΆμΆ' λ²νΌμ μ€ννμ¬ JSON νμΌμ μμ±νμΈμ.",
"νμΌ μμ", MessageBoxButton.OK, MessageBoxImage.Information);
@@ -1082,7 +1385,7 @@ namespace DwgExtractorManual
LogMessage("β λ§€ν λ°μ΄ν° νμΌμ μ°Ύμ μ μμ΅λλ€.");
LogMessage("π‘ λ¨Όμ 'DWG μ 보 μΆμΆ' λ²νΌμ μ€ννμ¬ λ§€ν λ°μ΄ν°λ₯Ό μμ±νμΈμ.");
- System.Windows.MessageBox.Show(
+ ShowMessageBox(
"λ§€ν λ°μ΄ν° νμΌμ μ°Ύμ μ μμ΅λλ€.\n\n" +
"λ¨Όμ 'DWG μ 보 μΆμΆ' λ²νΌμ μ€ννμ¬ λ§€ν λ°μ΄ν°λ₯Ό μμ±νμΈμ.",
"νμΌ μμ", MessageBoxButton.OK, MessageBoxImage.Information);
@@ -1100,15 +1403,13 @@ namespace DwgExtractorManual
await ShowJsonPreview(latestJsonFile);
// μ¬μ©μ νμΈ
- var result = System.Windows.MessageBox.Show(
+ var result = ShowConfirmationDialog(
$"λ€μ νμΌλ€λ‘ Excel λ§€νμ μ
λ°μ΄νΈνμκ² μ΅λκΉ?\n\n" +
$"π PDF JSON: {Path.GetFileName(latestJsonFile)}\n" +
$"π λ§€ν λ°μ΄ν°: {Path.GetFileName(latestMappingDataFile)}\n" +
$"π
μμ±: {File.GetCreationTime(latestJsonFile):yyyy-MM-dd HH:mm:ss}\n" +
$"π ν¬κΈ°: {new FileInfo(latestJsonFile).Length / 1024:N0} KB",
- "λ§€ν μ
λ°μ΄νΈ νμΈ",
- MessageBoxButton.YesNo,
- MessageBoxImage.Question);
+ "λ§€ν μ
λ°μ΄νΈ νμΈ");
if (result != MessageBoxResult.Yes)
{
@@ -1165,7 +1466,7 @@ namespace DwgExtractorManual
LogMessage($"β
Excel λ§€ν λ³ν© μλ£: {Path.GetFileName(completeExcelPath)}");
LogMessage("π DWG κ°κ³Ό PDF κ°μ΄ λͺ¨λ ν¬ν¨λ ν΅ν© Excel νμΌμ΄ μμ±λμμ΅λλ€.");
- System.Windows.MessageBox.Show(
+ ShowMessageBox(
$"Excel λ§€ν λ³ν©μ΄ μλ£λμμ΅λλ€!\n\n" +
$"π μ¬μ©λ JSON: {Path.GetFileName(latestJsonFile)}\n" +
$"π μμ±λ νμΌ: {Path.GetFileName(completeExcelPath)}\n" +
@@ -1254,6 +1555,302 @@ namespace DwgExtractorManual
}
}
+ ///
+ /// μλ μ²λ¦¬ λ²νΌ ν΄λ¦ μ΄λ²€νΈ
+ ///
+ private async void BtnAuto_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ // μ
λ ₯ κ²μ¦
+ if (string.IsNullOrEmpty(txtSourceFolder.Text))
+ {
+ ShowMessageBox("μμ€ ν΄λλ₯Ό μ νν΄μ£ΌμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ if (string.IsNullOrEmpty(txtResultFolder.Text))
+ {
+ ShowMessageBox("κ²°κ³Ό μ μ₯ ν΄λλ₯Ό μ νν΄μ£ΌμΈμ.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ string rootFolder = txtSourceFolder.Text;
+ string resultFolder = txtResultFolder.Text;
+
+ if (!Directory.Exists(rootFolder))
+ {
+ ShowMessageBox("μμ€ ν΄λκ° μ‘΄μ¬νμ§ μμ΅λλ€.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ if (!Directory.Exists(resultFolder))
+ {
+ ShowMessageBox("κ²°κ³Ό μ μ₯ ν΄λκ° μ‘΄μ¬νμ§ μμ΅λλ€.", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ // 리ν ν΄λλ€ μ°ΎκΈ°
+ LogMessage("π 리ν ν΄λ κ²μ μ€...");
+ var leafFolders = FindLeafFolders(rootFolder);
+
+ if (leafFolders.Count == 0)
+ {
+ ShowMessageBox("μ²λ¦¬ν 리ν ν΄λκ° μμ΅λλ€.", "μ 보", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ LogMessage($"π λ°κ²¬λ 리ν ν΄λ: {leafFolders.Count}κ°");
+ foreach (var folder in leafFolders)
+ {
+ LogMessage($" ββ {folder}");
+ }
+
+ // μ¬μ©μ νμΈ
+ var result = ShowConfirmationDialog(
+ $"μ΄ {leafFolders.Count}κ°μ 리ν ν΄λλ₯Ό μλ μ²λ¦¬νμκ² μ΅λκΉ?\n\n" +
+ "κ° ν΄λλ§λ€ DWG μΆμΆ β PDF μΆμΆ β ν©μΉκΈ°κ° μμ°¨μ μΌλ‘ μ€νλ©λλ€.",
+ "μλ μ²λ¦¬ νμΈ");
+
+ if (result != MessageBoxResult.Yes)
+ {
+ return;
+ }
+
+ // UI μν λ³κ²½
+ SetButtonsEnabled(false);
+ progressBar.Value = 0;
+ UpdateStatus("π€ μλ μ²λ¦¬ μμ...");
+
+ // μλ μ²λ¦¬ λͺ¨λ νμ±ν
+ isAutoProcessing = true;
+
+ await ProcessLeafFoldersAutomatically(leafFolders, resultFolder);
+
+ ShowMessageBox(
+ $"μλ μ²λ¦¬κ° μλ£λμμ΅λλ€!\n\n" +
+ $"μ²λ¦¬λ ν΄λ: {leafFolders.Count}κ°\n" +
+ $"κ²°κ³Ό μ μ₯ μμΉ: {resultFolder}",
+ "μλ£",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β μλ μ²λ¦¬ μ€ μ€λ₯: {ex.Message}");
+ ShowMessageBox($"μλ μ²λ¦¬ μ€ μ€λ₯κ° λ°μνμ΅λλ€:\n{ex.Message}", "μ€λ₯", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ finally
+ {
+ SetButtonsEnabled(true);
+ progressBar.Value = 0;
+ UpdateStatus("β
μ€λΉ");
+
+ // μλ μ²λ¦¬ λͺ¨λ λΉνμ±ν
+ isAutoProcessing = false;
+ }
+ }
+
+ ///
+ /// ν΄λμμ 리ν ν΄λλ€(νμ ν΄λκ° μλ ν΄λ)μ μ¬κ·μ μΌλ‘ μ°Ύμ΅λλ€.
+ ///
+ /// λ£¨νΈ ν΄λ κ²½λ‘
+ /// 리ν ν΄λ κ²½λ‘ λͺ©λ‘
+ private List FindLeafFolders(string rootPath)
+ {
+ var leafFolders = new List();
+
+ try
+ {
+ FindLeafFoldersRecursive(rootPath, leafFolders);
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β 리ν ν΄λ κ²μ μ€ μ€λ₯: {ex.Message}");
+ }
+
+ return leafFolders;
+ }
+
+ ///
+ /// μ¬κ·μ μΌλ‘ 리ν ν΄λλ₯Ό μ°Ύλ ν¬νΌ λ©μλ
+ ///
+ /// νμ¬ ν΄λ κ²½λ‘
+ /// 리ν ν΄λ λͺ©λ‘
+ private void FindLeafFoldersRecursive(string currentPath, List leafFolders)
+ {
+ try
+ {
+ var subDirectories = Directory.GetDirectories(currentPath);
+
+ if (subDirectories.Length == 0)
+ {
+ // νμ ν΄λκ° μμΌλ©΄ 리ν ν΄λ
+ leafFolders.Add(currentPath);
+ }
+ else
+ {
+ // νμ ν΄λκ° μμΌλ©΄ μ¬κ· νΈμΆ
+ foreach (var subDir in subDirectories)
+ {
+ FindLeafFoldersRecursive(subDir, leafFolders);
+ }
+ }
+ }
+ catch (UnauthorizedAccessException)
+ {
+ LogMessage($"β οΈ μ κ·Ό κΆν μμ: {currentPath}");
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β ν΄λ μ²λ¦¬ μ€ μ€λ₯ ({currentPath}): {ex.Message}");
+ }
+ }
+
+ ///
+ /// 리ν ν΄λλ€μ μλμΌλ‘ μ²λ¦¬ν©λλ€.
+ ///
+ /// μ²λ¦¬ν 리ν ν΄λ λͺ©λ‘
+ /// κ²°κ³Ό μ μ₯ κΈ°λ³Έ ν΄λ
+ private async Task ProcessLeafFoldersAutomatically(List leafFolders, string resultBaseFolder)
+ {
+ int totalFolders = leafFolders.Count;
+ int currentFolderIndex = 0;
+
+ foreach (var leafFolder in leafFolders)
+ {
+ currentFolderIndex++;
+ try
+ {
+ LogMessage($"π [{currentFolderIndex}/{totalFolders}] μ²λ¦¬ μμ: {leafFolder}");
+
+ // ν΄λ κ²½λ‘λ₯Ό νμΌλͺ
μΌλ‘ λ³ν (κ²½λ‘ κ΅¬λΆμλ₯Ό '_'λ‘ λ³κ²½)
+ string rootFolderPath = txtSourceFolder.Text.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+ string relativePath = Path.GetRelativePath(rootFolderPath, leafFolder);
+ string excelFileName = relativePath.Replace(Path.DirectorySeparatorChar, '_').Replace(Path.AltDirectorySeparatorChar, '_') + ".xlsx";
+ string excelFilePath = Path.Combine(resultBaseFolder, excelFileName);
+
+ // μ§νλ₯ μ
λ°μ΄νΈ
+ double baseProgress = ((double)(currentFolderIndex - 1) / totalFolders) * 100;
+ progressBar.Value = baseProgress;
+
+ // 1. DWG μΆμΆ
+ LogMessage($"π§ [{currentFolderIndex}/{totalFolders}] DWG μΆμΆ μμ...");
+ UpdateStatus($"π§ DWG μΆμΆ μ€... ({currentFolderIndex}/{totalFolders})");
+
+ await ProcessFiles(leafFolder);
+
+ progressBar.Value = baseProgress + (100.0 / totalFolders) * 0.33;
+ LogMessage($"β
[{currentFolderIndex}/{totalFolders}] DWG μΆμΆ μλ£");
+
+ // 2μ΄ λκΈ° (μλ νμ΄λ° 볡μ - μ±κΈν€ Servicesλ‘ μΆ©λ ν΄κ²°λ¨)
+ await Task.Delay(2000);
+
+ // 2. PDF μΆμΆ
+ LogMessage($"π [{currentFolderIndex}/{totalFolders}] PDF μΆμΆ μμ...");
+ UpdateStatus($"π PDF μΆμΆ μ€... ({currentFolderIndex}/{totalFolders})");
+
+ // νμ¬ ν΄λμμ PDF νμΌ μ°ΎκΈ°
+ var pdfFiles = new DirectoryInfo(leafFolder)
+ .GetFiles("*.pdf", SearchOption.AllDirectories)
+ .ToArray();
+
+ if (pdfFiles.Length == 0)
+ {
+ LogMessage($"β οΈ [{currentFolderIndex}/{totalFolders}] PDF νμΌμ΄ μμ - PDF μΆμΆ 건λλ");
+ }
+ else
+ {
+ await ProcessPdfFiles(pdfFiles);
+ }
+
+ progressBar.Value = baseProgress + (100.0 / totalFolders) * 0.66;
+ LogMessage($"β
[{currentFolderIndex}/{totalFolders}] PDF μΆμΆ μλ£");
+
+ // 3μ΄ λκΈ°
+ await Task.Delay(3000);
+
+ // 3. ν©μΉκΈ° λ° Excel νμΌ μ΄λ¦ λ³κ²½
+ LogMessage($"π [{currentFolderIndex}/{totalFolders}] ν©μΉκΈ° μμ...");
+ UpdateStatus($"π ν©μΉκΈ° μ€... ({currentFolderIndex}/{totalFolders})");
+
+ await MergeLatestPdfResults();
+
+ // μμ±λ Excel νμΌμ λͺ©ν μ΄λ¦μΌλ‘ λ³κ²½
+ await RenameLatestExcelFile(resultBaseFolder, excelFilePath);
+
+ progressBar.Value = baseProgress + (100.0 / totalFolders);
+ LogMessage($"β
[{currentFolderIndex}/{totalFolders}] μ²λ¦¬ μλ£: {excelFileName}");
+
+ // 2μ΄ λκΈ° ν λ€μ ν΄λ μ²λ¦¬
+ if (currentFolderIndex < totalFolders)
+ {
+ await Task.Delay(2000);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β [{currentFolderIndex}/{totalFolders}] ν΄λ μ²λ¦¬ μ€ν¨ ({leafFolder}): {ex.Message}");
+ LogMessage($"βοΈ [{currentFolderIndex}/{totalFolders}] λ€μ ν΄λλ‘ κ³μ μ§ν");
+
+ // μ€λ₯ λ°μ μ μ μ λκΈ° ν λ€μ ν΄λ μ²λ¦¬
+ await Task.Delay(2000);
+ continue;
+ }
+ }
+
+ LogMessage($"π μλ μ²λ¦¬ μλ£! μ΄ {totalFolders}κ° ν΄λ μ²λ¦¬λ¨");
+ UpdateStatus("β
μλ μ²λ¦¬ μλ£");
+ }
+
+ ///
+ /// μ΅μ Excel νμΌμ λͺ©ν κ²½λ‘λ‘ μ΄λ¦ λ³κ²½
+ ///
+ /// κ²°κ³Ό ν΄λ
+ /// λͺ©ν νμΌ κ²½λ‘
+ private async Task RenameLatestExcelFile(string resultFolder, string targetPath)
+ {
+ try
+ {
+ // μ΅μ *_Complete_Mapping_Merged.xlsx νμΌ μ°ΎκΈ°
+ var excelFiles = Directory.GetFiles(resultFolder, "*_Complete_Mapping_Merged.xlsx")
+ .Where(f => !Path.GetFileName(f).StartsWith("~$"))
+ .OrderByDescending(f => File.GetCreationTime(f))
+ .ToList();
+
+ if (excelFiles.Any())
+ {
+ string latestFile = excelFiles.First();
+
+ // λͺ©ν νμΌμ΄ μ΄λ―Έ μ‘΄μ¬νλ©΄ μμ
+ if (File.Exists(targetPath))
+ {
+ File.Delete(targetPath);
+ }
+
+ // νμΌ μ΄λ¦ λ³κ²½
+ File.Move(latestFile, targetPath);
+ LogMessage($"π Excel νμΌ μ΄λ¦ λ³κ²½λ¨: {Path.GetFileName(targetPath)}");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"β οΈ Excel νμΌ μ΄λ¦ λ³κ²½ μ€ν¨: {ex.Message}");
+ }
+ }
+
+ ///
+ /// λ²νΌλ€μ νμ±ν μνλ₯Ό μ€μ ν©λλ€.
+ ///
+ /// νμ±ν μ¬λΆ
+ private void SetButtonsEnabled(bool enabled)
+ {
+ btnExtract.IsEnabled = enabled;
+ btnPdfExtract.IsEnabled = enabled;
+ btnMerge.IsEnabled = enabled;
+ btnAuto.IsEnabled = enabled;
+ }
+
protected override void OnClosed(EventArgs e)
{
_timer?.Stop();
diff --git a/Models/ExportExcel.cs b/Models/ExportExcel.cs
index 5f1e922..8c0c8ce 100644
--- a/Models/ExportExcel.cs
+++ b/Models/ExportExcel.cs
@@ -21,7 +21,7 @@ namespace DwgExtractorManual.Models
///
internal class ExportExcel : IDisposable
{
- // ODA μλΉμ€ κ°μ²΄
+ // ODA μλΉμ€ κ°μ²΄ (managed by singleton)
private Services appServices;
// Excel COM κ°μ²΄λ€
@@ -72,7 +72,7 @@ namespace DwgExtractorManual.Models
}
Debug.WriteLine("π ODA μ΄κΈ°ν μ€...");
- ActivateAndInitializeODA();
+ InitializeTeighaServices();
Debug.WriteLine("π Excel μ΄κΈ°ν μ€...");
InitializeExcel();
}
@@ -93,13 +93,20 @@ namespace DwgExtractorManual.Models
}
}
- // ODA μ ν νμ±ν λ° μ΄κΈ°ν
- private void ActivateAndInitializeODA()
+ // Teigha μλΉμ€ μ΄κΈ°ν (μ±κΈν€ μ¬μ©)
+ private void InitializeTeighaServices()
{
- var userInfo = "c2FtYW4gZW5naW5lZXJpbmc=";
- var userSignature = "F0kuQTmtVpHtvl/TgaFVGE92/YqGmYR9SLoXckEjnOk8NoAQh7Sg6GQruVC04JqD4C/IipxJYqpqvMfMc2auRMG+cAJCKqKUE2djIMdkUdb+C5IVx2c97fcK5ba3n8DDvB54Upokajl+6j12yD8h8MKGOR3Z3zysObeXD62bFpQgp00GCYTqlxEZtTIRjHIPAfJfix8Y0jtXWWYyVJ3LYOu86as5xtx+hY1aakpYIJiQk/6pGd84qSn/9K1w8nxR7UrFzieDeQ/xM58BHSD4u/ZxVJwvv6Uy10tsdBFBTvfJMAFp05Y7yeyeCNr100tA3iOfmWoXAVRHfxnkPfiYR54aK04QI+R6OGkI+yd1oR5BtmN6BdDt3z8KYK5EpFGJGiJIGoUy5PvkYdJ2VV6xe9JWBiIJuI/tDn1Y+uyTQFA9qaDHnOURriXsRGfy8reDPf1eejybSJxWKkpilG6RXhq3xHlCkjZzh1Q45S+xYXNGatcWMm9nkn20M8Ke5JEVaI9w/p2GE36CHRtRQbt8kfPmsbWNXJCFr4svHW2MPbCKWoyn5XEyMWBnuAKi74zvczB13DKjf29SqSIgF5k/hwy2QrgvnaKzY1k8bw8w2/k0vJXcS3GKOB/ZYDle1tf/lkAD1HtnF9zE18TiXhVnqwAVjwg4ui1RPLn/LMs6b5Y=";
- Services.odActivate(userInfo, userSignature);
- appServices = new Services();
+ try
+ {
+ Debug.WriteLine("[DEBUG] TeighaServicesManagerλ₯Ό ν΅ν Services νλ μ€...");
+ appServices = TeighaServicesManager.Instance.AcquireServices();
+ Debug.WriteLine($"[DEBUG] Services νλ μ±κ³΅. Reference Count: {TeighaServicesManager.Instance.ReferenceCount}");
+ }
+ catch (Teigha.Runtime.Exception ex)
+ {
+ Debug.WriteLine($"[DEBUG] Teigha Services μ΄κΈ°ν μ€ν¨: {ex.Message}");
+ throw;
+ }
}
// Excel μ ν리μΌμ΄μ
λ° μν¬μνΈ μ΄κΈ°ν
@@ -603,14 +610,31 @@ namespace DwgExtractorManual.Models
return false;
}
- // JSON νμΌ μ½κΈ°
- string jsonContent = File.ReadAllText(jsonFilePath);
- JObject jsonData = JObject.Parse(jsonContent);
+ // JSON νμΌ μ½κΈ° λ° μ 리
+ string jsonContent = File.ReadAllText(jsonFilePath, System.Text.Encoding.UTF8);
+ Debug.WriteLine($"[DEBUG] JSON νμΌ ν¬κΈ°: {jsonContent.Length} bytes");
+
+ // JSON λ΄μ© μ 리 (μ£Όμ μ κ±° λ±)
+ jsonContent = CleanJsonContent(jsonContent);
+
+ JObject jsonData;
+ try
+ {
+ jsonData = JObject.Parse(jsonContent);
+ }
+ catch (Newtonsoft.Json.JsonReaderException jsonEx)
+ {
+ Debug.WriteLine($"β JSON νμ± μ€λ₯: {jsonEx.Message}");
+ Debug.WriteLine($"β JSON λ΄μ© 미리보기 (첫 500μ):");
+ Debug.WriteLine(jsonContent.Length > 500 ? jsonContent.Substring(0, 500) + "..." : jsonContent);
+ throw new System.Exception($"PDF λΆμ JSON νμΌ νμ± μ€ν¨: {jsonEx.Message}\nνμΌ: {jsonFilePath}");
+ }
var results = jsonData["results"] as JArray;
if (results == null)
{
Debug.WriteLine("β JSONμμ 'results' λ°°μ΄μ μ°Ύμ μ μμ΅λλ€.");
+ Debug.WriteLine($"β JSON λ£¨νΈ ν€λ€: {string.Join(", ", jsonData.Properties().Select(p => p.Name))}");
return false;
}
@@ -1032,7 +1056,21 @@ namespace DwgExtractorManual.Models
string jsonContent = File.ReadAllText(filePath, System.Text.Encoding.UTF8);
Debug.WriteLine($"[DEBUG] JSON λ΄μ© κΈΈμ΄: {jsonContent.Length}");
- var deserializedData = JsonConvert.DeserializeObject>>(jsonContent);
+ // JSON λ΄μ© μ 리 (μ£Όμ μ κ±° λ±)
+ jsonContent = CleanJsonContent(jsonContent);
+
+ Dictionary> deserializedData;
+ try
+ {
+ deserializedData = JsonConvert.DeserializeObject>>(jsonContent);
+ }
+ catch (Newtonsoft.Json.JsonReaderException jsonEx)
+ {
+ Debug.WriteLine($"β JSON νμ± μ€λ₯: {jsonEx.Message}");
+ Debug.WriteLine($"β JSON λ΄μ© 미리보기 (첫 500μ):");
+ Debug.WriteLine(jsonContent.Length > 500 ? jsonContent.Substring(0, 500) + "..." : jsonContent);
+ throw new System.Exception($"λ§€ν JSON νμΌ νμ± μ€ν¨: {jsonEx.Message}\nνμΌ: {filePath}");
+ }
// μλ‘μ΄ λμ
λ리 μ΄κΈ°ν
FileToMapkeyToLabelTagValuePdf.Clear();
@@ -1146,14 +1184,31 @@ namespace DwgExtractorManual.Models
return;
}
- // JSON νμΌ μ½κΈ°
- string jsonContent = File.ReadAllText(jsonFilePath);
- JObject jsonData = JObject.Parse(jsonContent);
+ // JSON νμΌ μ½κΈ° λ° μ 리
+ string jsonContent = File.ReadAllText(jsonFilePath, System.Text.Encoding.UTF8);
+ Debug.WriteLine($"[DEBUG] JSON νμΌ ν¬κΈ°: {jsonContent.Length} bytes");
+
+ // JSON λ΄μ© μ 리 (μ£Όμ μ κ±° λ±)
+ jsonContent = CleanJsonContent(jsonContent);
+
+ JObject jsonData;
+ try
+ {
+ jsonData = JObject.Parse(jsonContent);
+ }
+ catch (Newtonsoft.Json.JsonReaderException jsonEx)
+ {
+ Debug.WriteLine($"β JSON νμ± μ€λ₯: {jsonEx.Message}");
+ Debug.WriteLine($"β JSON λ΄μ© 미리보기 (첫 500μ):");
+ Debug.WriteLine(jsonContent.Length > 500 ? jsonContent.Substring(0, 500) + "..." : jsonContent);
+ throw new System.Exception($"PDF λΆμ JSON νμΌ νμ± μ€ν¨: {jsonEx.Message}\nνμΌ: {jsonFilePath}");
+ }
var results = jsonData["results"] as JArray;
if (results == null)
{
Debug.WriteLine("β JSONμμ 'results' λ°°μ΄μ μ°Ύμ μ μμ΅λλ€.");
+ Debug.WriteLine($"β JSON λ£¨νΈ ν€λ€: {string.Join(", ", jsonData.Properties().Select(p => p.Name))}");
return;
}
@@ -1229,17 +1284,158 @@ namespace DwgExtractorManual.Models
}
}
+ ///
+ /// JSON λ΄μ©μ μ 리νμ¬ νμ± κ°λ₯ν μνλ‘ λ§λλλ€.
+ /// μ£Όμ μ κ±° λ° κΈ°ν 무ν¨ν λ¬Έμ μ²λ¦¬
+ ///
+ /// μλ³Έ JSON λ΄μ©
+ /// μ 리λ JSON λ΄μ©
+ private string CleanJsonContent(string jsonContent)
+ {
+ if (string.IsNullOrEmpty(jsonContent))
+ return jsonContent;
+
+ try
+ {
+ // μ€λ³λ‘ μ²λ¦¬νμ¬ μ£Όμ μ κ±°
+ var lines = jsonContent.Split('\n');
+ var cleanedLines = new List();
+
+ bool inMultiLineComment = false;
+
+ foreach (string line in lines)
+ {
+ string processedLine = line;
+
+ // λ©ν°λΌμΈ μ£Όμ μ²λ¦¬ (/* */)
+ if (inMultiLineComment)
+ {
+ int endIndex = processedLine.IndexOf("*/");
+ if (endIndex >= 0)
+ {
+ processedLine = processedLine.Substring(endIndex + 2);
+ inMultiLineComment = false;
+ }
+ else
+ {
+ continue; // μ 체 λΌμΈμ΄ μ£Όμ
+ }
+ }
+
+ // λ©ν°λΌμΈ μ£Όμ μμ νμΈ
+ int multiLineStart = processedLine.IndexOf("/*");
+ if (multiLineStart >= 0)
+ {
+ int multiLineEnd = processedLine.IndexOf("*/", multiLineStart + 2);
+ if (multiLineEnd >= 0)
+ {
+ // κ°μ λΌμΈμμ μμνκ³ λλλ μ£Όμ
+ processedLine = processedLine.Substring(0, multiLineStart) +
+ processedLine.Substring(multiLineEnd + 2);
+ }
+ else
+ {
+ // λ©ν°λΌμΈ μ£Όμ μμ
+ processedLine = processedLine.Substring(0, multiLineStart);
+ inMultiLineComment = true;
+ }
+ }
+
+ // μ±κΈλΌμΈ μ£Όμ μ κ±° (//) - λ¬Έμμ΄ λ΄λΆμ //λ μ μΈ
+ bool inString = false;
+ bool escaped = false;
+ int commentIndex = -1;
+
+ for (int i = 0; i < processedLine.Length - 1; i++)
+ {
+ char current = processedLine[i];
+ char next = processedLine[i + 1];
+
+ if (escaped)
+ {
+ escaped = false;
+ continue;
+ }
+
+ if (current == '\\')
+ {
+ escaped = true;
+ continue;
+ }
+
+ if (current == '"')
+ {
+ inString = !inString;
+ continue;
+ }
+
+ if (!inString && current == '/' && next == '/')
+ {
+ commentIndex = i;
+ break;
+ }
+ }
+
+ if (commentIndex >= 0)
+ {
+ processedLine = processedLine.Substring(0, commentIndex);
+ }
+
+ // λΉ λΌμΈμ΄ μλλ©΄ μΆκ°
+ if (!string.IsNullOrWhiteSpace(processedLine))
+ {
+ cleanedLines.Add(processedLine);
+ }
+ }
+
+ string result = string.Join("\n", cleanedLines);
+ Debug.WriteLine($"[DEBUG] JSON μ 리 μλ£: {jsonContent.Length} -> {result.Length} bytes");
+ return result;
+ }
+ catch (System.Exception ex)
+ {
+ Debug.WriteLine($"β JSON μ 리 μ€ μ€λ₯: {ex.Message}");
+ // μ 리 μ€ν¨μ μλ³Έ λ°ν
+ return jsonContent;
+ }
+ }
+
public void Dispose()
{
- if (excelApplication != null)
+ try
{
- CloseExcelObjects();
- }
+ Debug.WriteLine("[DEBUG] ExportExcel Dispose μμ");
+
+ if (excelApplication != null)
+ {
+ Debug.WriteLine("[DEBUG] Excel κ°μ²΄ μ 리 μ€...");
+ CloseExcelObjects();
+ }
- if (appServices != null)
+ if (appServices != null)
+ {
+ Debug.WriteLine("[DEBUG] Teigha Services ν΄μ μ€...");
+ try
+ {
+ TeighaServicesManager.Instance.ReleaseServices();
+ Debug.WriteLine($"[DEBUG] Teigha Services ν΄μ μλ£. Remaining ref count: {TeighaServicesManager.Instance.ReferenceCount}");
+ }
+ catch (System.Exception ex)
+ {
+ Debug.WriteLine($"[DEBUG] Teigha Services ν΄μ μ€ μ€λ₯ (무μλ¨): {ex.Message}");
+ }
+ finally
+ {
+ appServices = null;
+ }
+ }
+
+ Debug.WriteLine("[DEBUG] ExportExcel Dispose μλ£");
+ }
+ catch (System.Exception ex)
{
- appServices.Dispose();
- appServices = null;
+ Debug.WriteLine($"[DEBUG] ExportExcel Dispose μ€ μ μ μ€λ₯: {ex.Message}");
+ // Disposal μ€λ₯λ λ‘κ·Έλ§ λ¨κΈ°κ³ κ³μ μ§ν
}
}
}
diff --git a/Models/SqlDatas.cs b/Models/SqlDatas.cs
index 085ef34..881225a 100644
--- a/Models/SqlDatas.cs
+++ b/Models/SqlDatas.cs
@@ -15,15 +15,22 @@ namespace DwgExtractorManual.Models
///
internal sealed class SqlDatas : IDisposable
{
- Services appServices; // ODA μ ν νμ±νμ©
+ Services appServices; // ODA μ ν νμ±νμ© (managed by singleton)
readonly string connectionString = "Host=localhost;Database=postgres;Username=postgres;Password=Qwer1234";
- void ActivateAndInitializeODA()
+ void InitializeTeighaServices()
{
- var userInfo = "c2FtYW4gZW5naW5lZXJpbmc=";
- var userSignature = "F0kuQTmtVpHtvl/TgaFVGE92/YqGmYR9SLoXckEjnOk8NoAQh7Sg6GQruVC04JqD4C/IipxJYqpqvMfMc2auRMG+cAJCKqKUE2djIMdkUdb+C5IVx2c97fcK5ba3n8DDvB54Upokajl+6j12yD8h8MKGOR3Z3zysObeXD62bFpQgp00GCYTqlxEZtTIRjHIPAfJfix8Y0jtXWWYyVJ3LYOu86as5xtx+hY1aakpYIJiQk/6pGd84qSn/9K1w8nxR7UrFzieDeQ/xM58BHSD4u/ZxVJwvv6Uy10tsdBFBTvfJMAFp05Y7yeyeCNr100tA3iOfmWoXAVRHfxnkPfiYR54aK04QI+R6OGkI+yd1oR5BtmN6BdDt3z8KYK5EpFGJGiJIGoUy5PvkYdJ2VV6xe9JWBiIJuI/tDn1Y+uyTQFA9qaDHnOURriXsRGfy8reDPf1eejybSJxWKkpilG6RXhq3xHlCkjZzh1Q45S+xYXNGatcWMm9nkn20M8Ke5JEVaI9w/p2GE36CHRtRQbt8kfPmsbWNXJCFr4svHW2MPbCKWoyn5XEyMWBnuAKi74zvczB13DKjf29SqSIgF5k/hwy2QrgvnaKzY1k8bw8w2/k0vJXcS3GKOB/ZYDle1tf/lkAD1HtnF9zE18TiXhVnqwAVjwg4ui1RPLn/LMs6b5Y=";
- Services.odActivate(userInfo, userSignature);
- appServices = new Services();
+ try
+ {
+ Debug.WriteLine("[SqlDatas] TeighaServicesManagerλ₯Ό ν΅ν Services νλ μ€...");
+ appServices = TeighaServicesManager.Instance.AcquireServices();
+ Debug.WriteLine($"[SqlDatas] Services νλ μ±κ³΅. Reference Count: {TeighaServicesManager.Instance.ReferenceCount}");
+ }
+ catch (Teigha.Runtime.Exception ex)
+ {
+ Debug.WriteLine($"[SqlDatas] Teigha Services μ΄κΈ°ν μ€ν¨: {ex.Message}");
+ throw;
+ }
}
void CreateTables()
@@ -78,7 +85,7 @@ namespace DwgExtractorManual.Models
public SqlDatas()
{
- ActivateAndInitializeODA();
+ InitializeTeighaServices();
CreateTables();
}
@@ -301,8 +308,20 @@ namespace DwgExtractorManual.Models
{
if (appServices != null)
{
- appServices.Dispose();
- appServices = null;
+ try
+ {
+ Debug.WriteLine("[SqlDatas] Teigha Services ν΄μ μ€...");
+ TeighaServicesManager.Instance.ReleaseServices();
+ Debug.WriteLine($"[SqlDatas] Teigha Services ν΄μ μλ£. Remaining ref count: {TeighaServicesManager.Instance.ReferenceCount}");
+ }
+ catch (Teigha.Runtime.Exception ex)
+ {
+ Debug.WriteLine($"[SqlDatas] Teigha Services ν΄μ μ€ μ€λ₯ (무μλ¨): {ex.Message}");
+ }
+ finally
+ {
+ appServices = null;
+ }
}
}
}
diff --git a/Models/TeighaServicesManager.cs b/Models/TeighaServicesManager.cs
new file mode 100644
index 0000000..201deb1
--- /dev/null
+++ b/Models/TeighaServicesManager.cs
@@ -0,0 +1,192 @@
+using System;
+using System.Diagnostics;
+using Teigha.Runtime;
+
+namespace DwgExtractorManual.Models
+{
+ ///
+ /// Singleton class to manage Teigha Services lifecycle and prevent disposal conflicts
+ ///
+ public sealed class TeighaServicesManager
+ {
+ private static readonly object _lock = new object();
+ private static TeighaServicesManager _instance = null;
+ private static Services _services = null;
+ private static int _referenceCount = 0;
+ private static bool _isActivated = false;
+
+ private TeighaServicesManager()
+ {
+ // Private constructor for singleton
+ }
+
+ public static TeighaServicesManager Instance
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ lock (_lock)
+ {
+ if (_instance == null)
+ {
+ _instance = new TeighaServicesManager();
+ }
+ }
+ }
+ return _instance;
+ }
+ }
+
+ ///
+ /// Acquires Teigha Services (creates if needed, increments reference count)
+ ///
+ /// The Services instance
+ public Services AcquireServices()
+ {
+ lock (_lock)
+ {
+ try
+ {
+ Debug.WriteLine($"[TeighaManager] AcquireServices - Current ref count: {_referenceCount}");
+
+ if (!_isActivated)
+ {
+ Debug.WriteLine("[TeighaManager] Activating ODA for first time...");
+ ActivateODA();
+ _isActivated = true;
+ }
+
+ if (_services == null)
+ {
+ Debug.WriteLine("[TeighaManager] Creating new Services instance...");
+ _services = new Services();
+ Debug.WriteLine("[TeighaManager] Services instance created successfully");
+ }
+
+ _referenceCount++;
+ Debug.WriteLine($"[TeighaManager] Services acquired - New ref count: {_referenceCount}");
+ return _services;
+ }
+ catch (Teigha.Runtime.Exception ex)
+ {
+ Debug.WriteLine($"[TeighaManager] Error acquiring services: {ex.Message}");
+ throw;
+ }
+ }
+ }
+
+ ///
+ /// Releases Teigha Services (decrements reference count, disposes when count reaches 0)
+ ///
+ public void ReleaseServices()
+ {
+ lock (_lock)
+ {
+ try
+ {
+ Debug.WriteLine($"[TeighaManager] ReleaseServices - Current ref count: {_referenceCount}");
+
+ if (_referenceCount > 0)
+ {
+ _referenceCount--;
+ Debug.WriteLine($"[TeighaManager] Services released - New ref count: {_referenceCount}");
+ }
+
+ // Don't dispose Services until app shutdown to prevent conflicts
+ // Just track reference count for debugging
+ if (_referenceCount == 0)
+ {
+ Debug.WriteLine("[TeighaManager] All references released (Services kept alive for app lifetime)");
+ }
+ }
+ catch (Teigha.Runtime.Exception ex)
+ {
+ Debug.WriteLine($"[TeighaManager] Error releasing services: {ex.Message}");
+ // Don't throw on release to prevent cascade failures
+ }
+ }
+ }
+
+ ///
+ /// Force dispose Services (only call on application shutdown)
+ ///
+ public void ForceDisposeServices()
+ {
+ lock (_lock)
+ {
+ try
+ {
+ Debug.WriteLine("[TeighaManager] Force disposing Services...");
+
+ if (_services != null)
+ {
+ _services.Dispose();
+ Debug.WriteLine("[TeighaManager] Services disposed successfully");
+ }
+
+ _services = null;
+ _referenceCount = 0;
+ _isActivated = false;
+
+ Debug.WriteLine("[TeighaManager] Force dispose completed");
+ }
+ catch (Teigha.Runtime.Exception ex)
+ {
+ Debug.WriteLine($"[TeighaManager] Error during force dispose: {ex.Message}");
+ // Reset state even if disposal fails
+ _services = null;
+ _referenceCount = 0;
+ _isActivated = false;
+ }
+ }
+ }
+
+ ///
+ /// Get current reference count (for debugging)
+ ///
+ public int ReferenceCount
+ {
+ get
+ {
+ lock (_lock)
+ {
+ return _referenceCount;
+ }
+ }
+ }
+
+ ///
+ /// Check if Services is active and valid
+ ///
+ public bool IsServicesActive
+ {
+ get
+ {
+ lock (_lock)
+ {
+ return _services != null && _isActivated;
+ }
+ }
+ }
+
+ private void ActivateODA()
+ {
+ try
+ {
+ Debug.WriteLine("[TeighaManager] Activating ODA...");
+
+ var userInfo = "c2FtYW4gZW5naW5lZXJpbmc=";
+ var userSignature = "F0kuQTmtVpHtvl/TgaFVGE92/YqGmYR9SLoXckEjnOk8NoAQh7Sg6GQruVC04JqD4C/IipxJYqpqvMfMc2auRMG+cAJCKqKUE2djIMdkUdb+C5IVx2c97fcK5ba3n8DDvB54Upokajl+6j12yD8h8MKGOR3Z3zysObeXD62bFpQgp00GCYTqlxEZtTIRjHIPAfJfix8Y0jtXWWYyVJ3LYOu86as5xtx+hY1aakpYIJiQk/6pGd84qSn/9K1w8nxR7UrFzieDeQ/xM58BHSD4u/ZxVJwvv6Uy10tsdBFBTvfJMAFp05Y7yeyeCNr100tA3iOfmWoXAVRHfxnkPfiYR54aK04QI+R6OGkI+yd1oR5BtmN6BdDt3z8KYK5EpFGJGiJIGoUy5PvkYdJ2VV6xe9JWBiIJuI/tDn1Y+uyTQFA9qaDHnOURriXsRGfy8reDPf1eejybSJxWKkpilG6RXhq3xHlCkjZzh1Q45S+xYXNGatcWMm9nkn20M8Ke5JEVaI9w/p2GE36CHRtRQbt8kfPmsbWNXJCFr4svHW2MPbCKWoyn5XEyMWBnuAKi74zvczB13DKjf29SqSIgF5k/hwy2QrgvnaKzY1k8bw8w2/k0vJXcS3GKOB/ZYDle1tf/lkAD1HtnF9zE18TiXhVnqwAVjwg4ui1RPLn/LMs6b5Y=";
+
+ Services.odActivate(userInfo, userSignature);
+ Debug.WriteLine("[TeighaManager] ODA activation successful");
+ }
+ catch (Teigha.Runtime.Exception ex)
+ {
+ Debug.WriteLine($"[TeighaManager] ODA activation failed: {ex.Message}");
+ throw;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/csharp_mapping_usage.cs b/csharp_mapping_usage.cs
index 8c427d0..8e639c1 100644
--- a/csharp_mapping_usage.cs
+++ b/csharp_mapping_usage.cs
@@ -56,15 +56,158 @@ public class FieldMapper
///
public static FieldMapper LoadFromFile(string jsonFilePath)
{
- string jsonContent = File.ReadAllText(jsonFilePath);
- var options = new JsonSerializerOptions
+ try
{
- PropertyNameCaseInsensitive = true,
- Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
- };
-
- var mappingData = JsonSerializer.Deserialize(jsonContent, options);
- return new FieldMapper(mappingData);
+ string jsonContent = File.ReadAllText(jsonFilePath, System.Text.Encoding.UTF8);
+ Console.WriteLine($"[DEBUG] λ§€ν ν
μ΄λΈ JSON νμΌ ν¬κΈ°: {jsonContent.Length} bytes");
+
+ // JSON λ΄μ© μ 리 (μ£Όμ μ κ±° λ±)
+ jsonContent = CleanJsonContent(jsonContent);
+
+ var options = new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true,
+ Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
+ AllowTrailingCommas = true
+ };
+
+ var mappingData = JsonSerializer.Deserialize(jsonContent, options);
+ Console.WriteLine($"[DEBUG] λ§€ν ν
μ΄λΈ λ‘λ μ±κ³΅: {mappingData?.MappingTable?.AilabelToSystems?.Count ?? 0}κ° νλͺ©");
+ return new FieldMapper(mappingData);
+ }
+ catch (JsonException jsonEx)
+ {
+ Console.WriteLine($"β λ§€ν ν
μ΄λΈ JSON νμ± μ€λ₯: {jsonEx.Message}");
+ Console.WriteLine($"β νμΌ: {jsonFilePath}");
+ if (File.Exists(jsonFilePath))
+ {
+ string content = File.ReadAllText(jsonFilePath);
+ Console.WriteLine($"β JSON λ΄μ© 미리보기 (첫 500μ):");
+ Console.WriteLine(content.Length > 500 ? content.Substring(0, 500) + "..." : content);
+ }
+ throw new Exception($"λ§€ν ν
μ΄λΈ JSON νμΌ νμ± μ€ν¨: {jsonEx.Message}\nνμΌ: {jsonFilePath}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"β λ§€ν ν
μ΄λΈ λ‘λ μ€ μ€λ₯: {ex.Message}");
+ throw;
+ }
+ }
+
+ ///
+ /// JSON λ΄μ©μ μ 리νμ¬ νμ± κ°λ₯ν μνλ‘ λ§λλλ€.
+ /// μ£Όμ μ κ±° λ° κΈ°ν 무ν¨ν λ¬Έμ μ²λ¦¬
+ ///
+ /// μλ³Έ JSON λ΄μ©
+ /// μ 리λ JSON λ΄μ©
+ private static string CleanJsonContent(string jsonContent)
+ {
+ if (string.IsNullOrEmpty(jsonContent))
+ return jsonContent;
+
+ try
+ {
+ // μ€λ³λ‘ μ²λ¦¬νμ¬ μ£Όμ μ κ±°
+ var lines = jsonContent.Split('\n');
+ var cleanedLines = new List();
+
+ bool inMultiLineComment = false;
+
+ foreach (string line in lines)
+ {
+ string processedLine = line;
+
+ // λ©ν°λΌμΈ μ£Όμ μ²λ¦¬ (/* */)
+ if (inMultiLineComment)
+ {
+ int endIndex = processedLine.IndexOf("*/");
+ if (endIndex >= 0)
+ {
+ processedLine = processedLine.Substring(endIndex + 2);
+ inMultiLineComment = false;
+ }
+ else
+ {
+ continue; // μ 체 λΌμΈμ΄ μ£Όμ
+ }
+ }
+
+ // λ©ν°λΌμΈ μ£Όμ μμ νμΈ
+ int multiLineStart = processedLine.IndexOf("/*");
+ if (multiLineStart >= 0)
+ {
+ int multiLineEnd = processedLine.IndexOf("*/", multiLineStart + 2);
+ if (multiLineEnd >= 0)
+ {
+ // κ°μ λΌμΈμμ μμνκ³ λλλ μ£Όμ
+ processedLine = processedLine.Substring(0, multiLineStart) +
+ processedLine.Substring(multiLineEnd + 2);
+ }
+ else
+ {
+ // λ©ν°λΌμΈ μ£Όμ μμ
+ processedLine = processedLine.Substring(0, multiLineStart);
+ inMultiLineComment = true;
+ }
+ }
+
+ // μ±κΈλΌμΈ μ£Όμ μ κ±° (//) - λ¬Έμμ΄ λ΄λΆμ //λ μ μΈ
+ bool inString = false;
+ bool escaped = false;
+ int commentIndex = -1;
+
+ for (int i = 0; i < processedLine.Length - 1; i++)
+ {
+ char current = processedLine[i];
+ char next = processedLine[i + 1];
+
+ if (escaped)
+ {
+ escaped = false;
+ continue;
+ }
+
+ if (current == '\\')
+ {
+ escaped = true;
+ continue;
+ }
+
+ if (current == '"')
+ {
+ inString = !inString;
+ continue;
+ }
+
+ if (!inString && current == '/' && next == '/')
+ {
+ commentIndex = i;
+ break;
+ }
+ }
+
+ if (commentIndex >= 0)
+ {
+ processedLine = processedLine.Substring(0, commentIndex);
+ }
+
+ // λΉ λΌμΈμ΄ μλλ©΄ μΆκ°
+ if (!string.IsNullOrWhiteSpace(processedLine))
+ {
+ cleanedLines.Add(processedLine);
+ }
+ }
+
+ string result = string.Join("\n", cleanedLines);
+ Console.WriteLine($"[DEBUG] λ§€ν ν
μ΄λΈ JSON μ 리 μλ£: {jsonContent.Length} -> {result.Length} bytes");
+ return result;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"β λ§€ν ν
μ΄λΈ JSON μ 리 μ€ μ€λ₯: {ex.Message}");
+ // μ 리 μ€ν¨μ μλ³Έ λ°ν
+ return jsonContent;
+ }
}
///
diff --git a/fletimageanalysis/mapping_table_json.json b/fletimageanalysis/mapping_table_json.json
index 787ed17..1db153d 100644
--- a/fletimageanalysis/mapping_table_json.json
+++ b/fletimageanalysis/mapping_table_json.json
@@ -73,13 +73,7 @@
"railway": "",
"docaikey": "CSCOP"
},
- //"μ¬μ
λͺ
_bot": {
- // "molit": "",
- // "expressway": "TD_CNAME",
- // "railway": "TD_CNAME",
- // "docaikey": "TDCNAME"
- //},
- "μ€κ³κ³΅κ΅¬_곡ꡬλͺ
": {
+ "μ€κ³κ³΅κ΅¬_곡ꡬλͺ
": {
"molit": "",
"expressway": "TD_DSECT",
"railway": "",