2025-07-06 19:30~ 21:35, 10:30 ~

Chrome Web Driver 추가(신규 복본검사 로직용)
도서관 검색버튼 추가
도서관 선택없이 검색시작을 누르면 오류 표시
도서관 DB 정보에 신규로직용 식별 키(SearcherNo:int) 추가
  - 광주광역시 남구 (문화, 청소년, 스마트, 푸른길)
This commit is contained in:
SeungHo Yang
2025-07-06 23:49:08 +09:00
parent 344659c1b9
commit b7c6e530dd
20 changed files with 1906 additions and 130 deletions

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="UniMarc.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/></startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /></startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
@@ -18,19 +18,31 @@
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://testws.baroservice.com/FAX.asmx" binding="basicHttpBinding"
bindingConfiguration="BaroService_FAXSoap" contract="BaroService_API.BaroService_FAXSoap"
name="BaroService_FAXSoap" />
<endpoint address="https://testws.baroservice.com/TI.asmx" binding="basicHttpBinding"
bindingConfiguration="BaroService_TISoap" contract="BaroService_TI.BaroService_TISoap"
name="BaroService_TISoap" />
<endpoint address="http://testws.baroservice.com/FAX.asmx" binding="basicHttpBinding" bindingConfiguration="BaroService_FAXSoap" contract="BaroService_API.BaroService_FAXSoap" name="BaroService_FAXSoap" />
<endpoint address="https://testws.baroservice.com/TI.asmx" binding="basicHttpBinding" bindingConfiguration="BaroService_TISoap" contract="BaroService_TI.BaroService_TISoap" name="BaroService_TISoap" />
</client>
</system.serviceModel>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Renci.SshNet" publicKeyToken="1cee9f8bde3db106" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-2020.0.1.0" newVersion="2020.0.1.0"/>
<assemblyIdentity name="Renci.SshNet" publicKeyToken="1cee9f8bde3db106" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2020.0.1.0" newVersion="2020.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

View File

@@ -132,6 +132,7 @@
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.IPText = new System.Windows.Forms.ToolStripLabel();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.lblStatus = new System.Windows.Forms.ToolStripLabel();
this.menuStrip1.SuspendLayout();
this.panel1.SuspendLayout();
this.toolStrip1.SuspendLayout();
@@ -761,48 +762,48 @@
this.ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ToolStripMenuItem});
this.ToolStripMenuItem.Name = "이용자관리ToolStripMenuItem";
this.ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
this.ToolStripMenuItem.Text = "이용자 관리";
//
// 신규사업자등록ToolStripMenuItem
//
this.ToolStripMenuItem.Name = "신규사업자등록ToolStripMenuItem";
this.ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.ToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
this.ToolStripMenuItem.Text = "사업자 관리";
this.ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click);
//
// 공지발송ToolStripMenuItem1
//
this.ToolStripMenuItem1.Name = "공지발송ToolStripMenuItem1";
this.ToolStripMenuItem1.Size = new System.Drawing.Size(180, 22);
this.ToolStripMenuItem1.Size = new System.Drawing.Size(178, 22);
this.ToolStripMenuItem1.Text = "공지 발송";
this.ToolStripMenuItem1.Click += new System.EventHandler(this.ToolStripMenuItem1_Click);
//
// 매출내역ToolStripMenuItem
//
this.ToolStripMenuItem.Name = "매출내역ToolStripMenuItem";
this.ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
this.ToolStripMenuItem.Text = "매출내역";
this.ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click);
//
// 이용자거래처조회ToolStripMenuItem
//
this.ToolStripMenuItem.Name = "이용자거래처조회ToolStripMenuItem";
this.ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
this.ToolStripMenuItem.Text = "이용자 거래처 조회";
this.ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click);
//
// 마크설정ToolStripMenuItem
//
this.ToolStripMenuItem.Name = "마크설정ToolStripMenuItem";
this.ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
this.ToolStripMenuItem.Text = "마크설정";
this.ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click);
//
// 일괄처리관리ToolStripMenuItem
//
this.ToolStripMenuItem.Name = "일괄처리관리ToolStripMenuItem";
this.ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.ToolStripMenuItem.Size = new System.Drawing.Size(178, 22);
this.ToolStripMenuItem.Text = "일괄처리 관리";
this.ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click);
//
@@ -1008,7 +1009,8 @@
this.botUserLabel,
this.toolStripSeparator2,
this.toolStripSeparator3,
this.IPText});
this.IPText,
this.lblStatus});
this.toolStrip1.Location = new System.Drawing.Point(0, 681);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(1259, 25);
@@ -1057,6 +1059,12 @@
this.IPText.Size = new System.Drawing.Size(154, 22);
this.IPText.Text = "접속 아이피 : 0.000.00.000";
//
// lblStatus
//
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(27, 22);
this.lblStatus.Text = "WD";
//
// Main
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
@@ -1188,5 +1196,6 @@
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
public System.Windows.Forms.ToolStripLabel IPText;
private System.Windows.Forms.ToolStripLabel lblStatus;
}
}

View File

@@ -27,6 +27,7 @@ using UniMarc.마크;
using UniMarc.Properties;
using UniMarc;
namespace WindowsFormsApp1
{
public partial class Main : Form
@@ -40,12 +41,17 @@ namespace WindowsFormsApp1
public Main()
{
InitializeComponent();
}
public string User_Name { get; internal set; }
private void Main_Load(object sender, EventArgs e)
{
this.Visible = false; // 메인폼을 먼저 숨김
#region "Log setting"
@@ -102,6 +108,8 @@ namespace WindowsFormsApp1
}
#region
public void SetBtnName()
{

View File

@@ -18,9 +18,15 @@ namespace WindowsFormsApp1
Application.SetCompatibleTextRenderingDefault(false);
DB_InitSetting();
UpdaterCheck();
Application.Run(new Main());
}
/// <summary>
/// factory client update checkd
/// </summary>

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.185")]
[assembly: AssemblyFileVersion("1.0.0.185")]
[assembly: AssemblyVersion("1.0.0.186")]
[assembly: AssemblyFileVersion("1.0.0.186")]

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace BokBonCheck
{
public class BookSearchResult
{
public string SiteName { get; set; }
public int BookCount { get; set; }
public string SearchTerm { get; set; }
public DateTime SearchTime { get; set; }
public string ErrorMessage { get; set; }
public bool IsSuccess { get; set; }
}
public class BookSearchService
{
private readonly List<ILibrarySearcher> _searchers;
public BookSearchService()
{
_searchers = new List<ILibrarySearcher>
{
};
}
public async Task<List<BookSearchResult>> SearchBooksAsync(string searchTerm)
{
var results = new List<BookSearchResult>();
foreach (var searcher in _searchers)
{
searcher.StartDriver();
var result = await searcher.SearchAsync(searchTerm);
results.Add(result);
//searcher.StopDriver();
}
return results;
}
/// <summary>
/// Return Searcher
/// </summary>
/// <param name="no"></param>
/// <returns></returns>
public ILibrarySearcher Get(int no)
{
return _searchers.Where(t => t.No == no).FirstOrDefault();
}
public void AddSearcher(ILibrarySearcher searcher)
{
if (!_searchers.Any(s => s.SiteName == searcher.SiteName))
{
_searchers.Add(searcher);
}
}
public void RemoveSearcher(string siteName)
{
var searcher = _searchers.FirstOrDefault(s => s.SiteName == siteName);
if (searcher != null)
{
_searchers.Remove(searcher);
}
}
public List<string> GetAvailableSites()
{
return _searchers.Select(s => s.SiteName).ToList();
}
public void ClearSearchers()
{
_searchers.Clear();
}
}
}

View File

@@ -0,0 +1,378 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;
using System.Reflection;
using System.Net.Http;
using System.Threading;
using System.IO.Compression;
namespace BokBonCheck
{
public static class ChromeDriverManager
{
private static string _driverPath = null;
public static async Task<string> SetupChromeDriverAsync(DownloadProgressForm progressForm = null)
{
try
{
// Chrome 버전 확인
var chromeVersion = GetChromeVersion();
Console.WriteLine($"설치된 Chrome 버전: {chromeVersion}");
if (progressForm != null)
{
progressForm.UpdateProgress(10, $"Chrome 버전 확인 중... ({chromeVersion})");
}
// 기존 드라이버 경로 확인
var existingDriverPath = GetExistingDriverPath();
if (!string.IsNullOrEmpty(existingDriverPath) && File.Exists(existingDriverPath))
{
Console.WriteLine($"기존 드라이버 발견: {existingDriverPath}");
// 기존 드라이버 테스트
if (await TestExistingDriver(existingDriverPath))
{
if (progressForm != null)
{
progressForm.UpdateProgress(100, "기존 드라이버 사용");
progressForm.SetCompleted("기존 드라이버를 사용합니다.");
}
_driverPath = existingDriverPath;
Environment.SetEnvironmentVariable("webdriver.chrome.driver", existingDriverPath);
return existingDriverPath;
}
else
{
Console.WriteLine("기존 드라이버 테스트 실패 - 새로 다운로드");
// 기존 드라이버가 작동하지 않으면 삭제
try
{
File.Delete(existingDriverPath);
Console.WriteLine("기존 드라이버 삭제됨");
}
catch (Exception ex)
{
Console.WriteLine($"기존 드라이버 삭제 실패: {ex.Message}");
}
}
}
if (progressForm != null)
{
progressForm.UpdateProgress(30, "Chrome 버전에 맞는 드라이버 다운로드 중...");
}
// WebDriverManager를 사용하여 설치된 Chrome 버전에 맞는 드라이버 다운로드
var driverManager = new DriverManager();
var driverPath = driverManager.SetUpDriver(new ChromeConfig(), "MatchingBrowser");
// 다운로드된 드라이버 경로 저장
_driverPath = driverPath;
// 환경 변수 설정
Environment.SetEnvironmentVariable("webdriver.chrome.driver", driverPath);
if (progressForm != null)
{
progressForm.UpdateProgress(100, "드라이버 다운로드 완료");
progressForm.SetCompleted("드라이버 다운로드 완료!");
}
Console.WriteLine($"ChromeDriver 경로: {driverPath}");
Console.WriteLine($"환경 변수 설정: webdriver.chrome.driver = {driverPath}");
return driverPath;
}
catch (Exception ex)
{
Console.WriteLine($"ChromeDriver 설정 오류: {ex.Message}");
if (progressForm != null)
{
progressForm.SetError($"설정 오류: {ex.Message}");
}
throw;
}
}
private static string GetExistingDriverPath()
{
try
{
// 환경 변수에서 확인
var envPath = Environment.GetEnvironmentVariable("webdriver.chrome.driver");
if (!string.IsNullOrEmpty(envPath) && File.Exists(envPath))
{
return envPath;
}
// WebDriverManager 캐시 폴더에서 확인
var cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".cache", "selenium");
if (Directory.Exists(cachePath))
{
var chromeDriverFiles = Directory.GetFiles(cachePath, "chromedriver*", SearchOption.AllDirectories);
foreach (var file in chromeDriverFiles)
{
if (file.EndsWith(".exe") || !Path.HasExtension(file))
{
return file;
}
}
}
return null;
}
catch
{
return null;
}
}
public static string GetDriverPath()
{
return _driverPath;
}
private static string GetChromeVersion()
{
try
{
// Windows에서 Chrome 설치 경로 확인
var chromePaths = new[]
{
@"C:\Program Files\Google\Chrome\Application\chrome.exe",
@"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
@"Google\Chrome\Application\chrome.exe")
};
foreach (var path in chromePaths)
{
if (File.Exists(path))
{
var versionInfo = FileVersionInfo.GetVersionInfo(path);
var version = versionInfo.FileVersion;
Console.WriteLine($"Chrome 버전 감지: {version} (경로: {path})");
return version;
}
}
return "알 수 없음";
}
catch (Exception ex)
{
Console.WriteLine($"Chrome 버전 감지 실패: {ex.Message}");
return "확인 실패";
}
}
public static bool IsChromeInstalled()
{
try
{
var chromePaths = new[]
{
@"C:\Program Files\Google\Chrome\Application\chrome.exe",
@"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
@"Google\Chrome\Application\chrome.exe")
};
foreach (var path in chromePaths)
{
if (File.Exists(path))
{
return true;
}
}
return false;
}
catch
{
return false;
}
}
public static async Task<bool> TestChromeDriverAsync(DownloadProgressForm progressForm = null)
{
try
{
var driverPath = await SetupChromeDriverAsync(progressForm);
if (progressForm != null)
{
progressForm.UpdateProgress(50, "드라이버 테스트 중...");
}
// ChromeDriver 서비스 설정
var service = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath));
service.HideCommandPromptWindow = true;
// 간단한 테스트 실행
var options = new OpenQA.Selenium.Chrome.ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--no-sandbox");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-gpu");
options.AddArgument("--remote-debugging-port=0");
using (var driver = new OpenQA.Selenium.Chrome.ChromeDriver(service, options))
{
driver.Navigate().GoToUrl("https://www.google.com");
var title = driver.Title;
Console.WriteLine($"드라이버 테스트 성공: {title}");
if (progressForm != null)
{
progressForm.UpdateProgress(100, "드라이버 테스트 성공!");
progressForm.SetCompleted("드라이버 테스트 성공!");
}
return !string.IsNullOrEmpty(title);
}
}
catch (Exception ex)
{
Console.WriteLine($"ChromeDriver 테스트 실패: {ex.Message}");
if (progressForm != null)
{
progressForm.SetError($"테스트 실패: {ex.Message}");
}
return false;
}
}
public static void ClearDriverCache()
{
try
{
Console.WriteLine("Chrome 드라이버 캐시 정리 시작...");
// WebDriverManager 캐시 폴더 정리
var cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".cache", "selenium");
if (Directory.Exists(cachePath))
{
Directory.Delete(cachePath, true);
Console.WriteLine($"WebDriverManager 캐시 정리됨: {cachePath}");
}
// 환경 변수에서 설정된 드라이버 경로도 정리
var envDriverPath = Environment.GetEnvironmentVariable("webdriver.chrome.driver");
if (!string.IsNullOrEmpty(envDriverPath) && File.Exists(envDriverPath))
{
try
{
File.Delete(envDriverPath);
Console.WriteLine($"환경 변수 드라이버 삭제됨: {envDriverPath}");
}
catch (Exception ex)
{
Console.WriteLine($"환경 변수 드라이버 삭제 실패: {ex.Message}");
}
}
// 저장된 드라이버 경로도 정리
if (!string.IsNullOrEmpty(_driverPath) && File.Exists(_driverPath))
{
try
{
File.Delete(_driverPath);
Console.WriteLine($"저장된 드라이버 삭제됨: {_driverPath}");
}
catch (Exception ex)
{
Console.WriteLine($"저장된 드라이버 삭제 실패: {ex.Message}");
}
}
_driverPath = null;
Environment.SetEnvironmentVariable("webdriver.chrome.driver", null);
Console.WriteLine("Chrome 드라이버 캐시 정리 완료");
}
catch (Exception ex)
{
Console.WriteLine($"캐시 정리 실패: {ex.Message}");
}
}
public static bool IsDriverReady()
{
try
{
var driverPath = GetExistingDriverPath();
if (string.IsNullOrEmpty(driverPath) || !File.Exists(driverPath))
{
Console.WriteLine("기존 드라이버가 없습니다.");
return false;
}
Console.WriteLine($"드라이버 준비 상태 확인: {driverPath}");
// 간단한 테스트 실행
var service = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath));
service.HideCommandPromptWindow = true;
var options = new OpenQA.Selenium.Chrome.ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--no-sandbox");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-gpu");
options.AddArgument("--remote-debugging-port=0");
using (var driver = new OpenQA.Selenium.Chrome.ChromeDriver(service, options))
{
driver.Navigate().GoToUrl("https://www.google.com");
var result = !string.IsNullOrEmpty(driver.Title);
Console.WriteLine($"드라이버 준비 상태: {(result ? "" : "")}");
return result;
}
}
catch (Exception ex)
{
Console.WriteLine($"드라이버 준비 상태 확인 실패: {ex.Message}");
return false;
}
}
private static async Task<bool> TestExistingDriver(string driverPath)
{
try
{
Console.WriteLine($"기존 드라이버 테스트: {driverPath}");
// ChromeDriver 서비스 설정
var service = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath));
service.HideCommandPromptWindow = true;
// 간단한 테스트 실행
var options = new OpenQA.Selenium.Chrome.ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--no-sandbox");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-gpu");
options.AddArgument("--remote-debugging-port=0");
using (var driver = new OpenQA.Selenium.Chrome.ChromeDriver(service, options))
{
driver.Navigate().GoToUrl("https://www.google.com");
var title = driver.Title;
Console.WriteLine($"드라이버 테스트 성공: {title}");
return !string.IsNullOrEmpty(title);
}
}
catch (Exception ex)
{
Console.WriteLine($"기존 드라이버 테스트 실패: {ex.Message}");
return false;
}
}
}
}

View File

@@ -0,0 +1,142 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading.Tasks;
namespace BokBonCheck
{
public partial class DownloadProgressForm : Form
{
private ProgressBar progressBar;
private Label lblStatus;
private Label lblProgress;
private Button btnCancel;
private bool isCancelled = false;
public DownloadProgressForm()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterScreen;
}
private void InitializeComponent()
{
this.Text = "Chrome 드라이버 다운로드";
this.Size = new Size(400, 150);
this.StartPosition = FormStartPosition.CenterParent;
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.ControlBox = false;
this.TopMost = true;
// 상태 라벨
lblStatus = new Label
{
Text = "Chrome 드라이버를 확인하고 있습니다...",
Location = new Point(20, 20),
Size = new Size(360, 20),
Font = new Font("맑은 고딕", 9),
TextAlign = ContentAlignment.MiddleCenter
};
// 진행률 라벨
lblProgress = new Label
{
Text = "0%",
Location = new Point(20, 50),
Size = new Size(360, 20),
Font = new Font("맑은 고딕", 10, FontStyle.Bold),
TextAlign = ContentAlignment.MiddleCenter,
ForeColor = Color.Blue
};
// 프로그레스 바
progressBar = new ProgressBar
{
Location = new Point(20, 80),
Size = new Size(360, 25),
Style = ProgressBarStyle.Continuous,
Minimum = 0,
Maximum = 100,
Value = 0
};
// 취소 버튼
btnCancel = new Button
{
Text = "취소",
Location = new Point(150, 115),
Size = new Size(100, 30),
Font = new Font("맑은 고딕", 9),
BackColor = Color.LightCoral
};
btnCancel.Click += BtnCancel_Click;
// 컨트롤 추가
this.Controls.AddRange(new Control[]
{
lblStatus, lblProgress, progressBar, btnCancel
});
}
private void BtnCancel_Click(object sender, EventArgs e)
{
isCancelled = true;
btnCancel.Enabled = false;
lblStatus.Text = "취소 중...";
}
public bool IsCancelled => isCancelled;
public void UpdateProgress(int percentage, string status = null)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<int, string>(UpdateProgress), percentage, status);
return;
}
progressBar.Value = Math.Min(percentage, 100);
lblProgress.Text = $"{percentage}%";
if (!string.IsNullOrEmpty(status))
{
lblStatus.Text = status;
}
}
public void SetCompleted(string message = "다운로드 완료!")
{
if (this.InvokeRequired)
{
this.Invoke(new Action<string>(SetCompleted), message);
return;
}
progressBar.Value = 100;
lblProgress.Text = "100%";
lblStatus.Text = message;
btnCancel.Text = "확인";
btnCancel.BackColor = Color.LightGreen;
btnCancel.Enabled = true;
}
public void SetError(string errorMessage)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<string>(SetError), errorMessage);
return;
}
lblStatus.Text = "오류 발생";
lblProgress.Text = "실패";
lblProgress.ForeColor = Color.Red;
btnCancel.Text = "확인";
btnCancel.BackColor = Color.LightCoral;
btnCancel.Enabled = true;
}
}
}

View File

@@ -0,0 +1,17 @@
using OpenQA.Selenium.Support.UI;
using System.Threading.Tasks;
namespace BokBonCheck
{
public interface ILibrarySearcher
{
int No { get; set; }
string SiteName { get; }
string SiteUrl { get; }
Task<BookSearchResult> SearchAsync(string searchTerm);
void StartDriver();
void StopDriver();
Task WaitForPageChange(WebDriverWait wait);
}
}

View File

@@ -0,0 +1,321 @@
using System;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System.Text.RegularExpressions;
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;
using System.IO;
using System.Runtime.InteropServices;
namespace BokBonCheck
{
public class KwangjuCityLibrarySearcher_choisangjun : KwangjuCityLibrarySearcher
{
public KwangjuCityLibrarySearcher_choisangjun(int no) : base(no)
{
SelectorValue = "MF";
SiteName = "광주시교육청통합도서관(분관최상준도서관)";
}
}
public class KwangjuCityLibrarySearcher_dagachi : KwangjuCityLibrarySearcher
{
public KwangjuCityLibrarySearcher_dagachi(int no) : base(no)
{
SelectorValue = "ME";
SiteName = "광주시교육청통합도서관(송정다가치문화도서관)";
}
}
public class KwangjuCityLibrarySearcher_central : KwangjuCityLibrarySearcher
{
public KwangjuCityLibrarySearcher_central(int no) : base(no)
{
SelectorValue = "MD";
SiteName = "광주시교육청통합도서관(중앙도서관)";
}
}
public class KwangjuCityLibrarySearcher_Student : KwangjuCityLibrarySearcher
{
public KwangjuCityLibrarySearcher_Student(int no) : base(no)
{
SelectorValue = "MC";
SiteName = "광주시교육청통합도서관(학생교육문화회관)";
}
}
public class KwangjuCityLibrarySearcher_Kumho : KwangjuCityLibrarySearcher
{
public KwangjuCityLibrarySearcher_Kumho(int no) : base(no)
{
SelectorValue = "MB";
SiteName = "광주시교육청통합도서관(금호평생교육관)";
}
}
public class KwangjuCityLibrarySearcher_Indi : KwangjuCityLibrarySearcher
{
public KwangjuCityLibrarySearcher_Indi(int no) : base(no)
{
SelectorValue = "MA";
SiteName = "광주시교육청통합도서관(학생독립운동기념회관)";
}
}
public abstract class KwangjuCityLibrarySearcher : ILibrarySearcher
{
public int No { get; set; }
public string SiteName { get; protected set; } = "광주시교육청통합도서관";
public string SiteUrl => "https://lib.gen.go.kr/main/site/search/bookSearch.do#simple";
protected string SelectorValue = "";
private ChromeDriver _driver;
private ChromeDriverService _service;
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_MINIMIZE = 6;
public KwangjuCityLibrarySearcher(int no)
{
this.No = no;
}
public void StartDriver()
{
if (_driver == null)
{
var driverPath = ChromeDriverManager.GetDriverPath();
if (string.IsNullOrEmpty(driverPath) || !File.Exists(driverPath))
{
driverPath = ChromeDriverManager.SetupChromeDriverAsync().GetAwaiter().GetResult();
}
_service = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath), Path.GetFileName(driverPath));
_service.HideCommandPromptWindow = true;
var options = new ChromeOptions();
options.AddArgument("--no-sandbox");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-gpu");
options.AddArgument("--window-size=1920,1080");
options.AddArgument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
options.AddArgument("--disable-blink-features=AutomationControlled");
options.AddExcludedArgument("enable-automation");
options.AddAdditionalOption("useAutomationExtension", false);
_driver = new ChromeDriver(_service, options);
((IJavaScriptExecutor)_driver).ExecuteScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
}
}
public void StopDriver()
{
if (_driver != null)
{
_driver.Quit();
_driver.Dispose();
_driver = null;
}
if (_service != null)
{
_service.Dispose();
_service = null;
}
}
virtual protected void SelectLibrary(WebDriverWait wait)
{
try
{
// 콤보박스(select) 요소 찾기
var selectElement = wait.Until(d => d.FindElement(By.CssSelector("#manage_code")));
var select = new OpenQA.Selenium.Support.UI.SelectElement(selectElement);
// value가 "MA"인 옵션 선택
select.SelectByValue(SelectorValue);
}
catch
{
// 예외 처리 (필요시 로깅 등)
}
}
public async Task<BookSearchResult> SearchAsync(string searchTerm)
{
var result = new BookSearchResult
{
SiteName = SiteName,
SearchTerm = searchTerm,
SearchTime = DateTime.Now
};
try
{
if (_driver == null)
throw new InvalidOperationException("드라이버가 시작되지 않았습니다. StartDriver()를 먼저 호출하세요.");
_driver.Navigate().GoToUrl(SiteUrl);
// 페이지 로딩 대기
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
// 모든 감지 방법이 끝나면 크롬창 최소화
IntPtr chromeWindow = FindWindow("Chrome_WidgetWin_1", null);
if (chromeWindow != IntPtr.Zero)
{
ShowWindow(chromeWindow, SW_MINIMIZE);
}
//대상도서관 선택
SelectLibrary(wait);
// 검색창 찾기
IWebElement searchBox = null;
try
{
// 여러 가능한 선택자 시도
var selectors = new[]
{
"input[id='search_txt']",
"input[type='text']",
};
foreach (var selector in selectors)
{
try
{
searchBox = wait.Until(d =>
{
var el = d.FindElement(By.CssSelector(selector));
return (el != null && el.Displayed && el.Enabled) ? el : null;
});
break;
}
catch
{
continue;
}
}
if (searchBox == null)
{
throw new Exception("검색창을 찾을 수 없습니다.");
}
}
catch (Exception ex)
{
throw new Exception($"검색창 찾기 실패: {ex.Message}");
}
// 혹시 readonly라면 속성 제거
((IJavaScriptExecutor)_driver).ExecuteScript("arguments[0].removeAttribute('readonly')", searchBox);
// 입력 전 clear
searchBox.Clear();
searchBox.SendKeys(searchTerm);
// 검색 버튼 클릭
IWebElement searchButton = null;
try
{
var buttonSelectors = new[]
{
"input[type='submit']",
};
foreach (var selector in buttonSelectors)
{
try
{
searchButton = _driver.FindElement(By.CssSelector(selector));
break;
}
catch
{
continue;
}
}
if (searchButton == null)
{
// Enter 키로 검색 시도
searchBox.SendKeys(Keys.Enter);
}
else
{
searchButton.Click();
}
}
catch (Exception ex)
{
// Enter 키로 검색 시도
searchBox.SendKeys(Keys.Enter);
}
// 페이지 변경을 감지하는 메서드
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
// 검색 결과 수 추출
var resultCount = ExtractBookCount(_driver);
result.BookCount = resultCount;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMessage = ex.Message;
result.BookCount = 0;
}
return result;
}
private int ExtractBookCount(IWebDriver driver)
{
try
{
// div.search-result 내부의 span에서 '전체 N' 텍스트 추출
var resultDiv = driver.FindElement(By.CssSelector("div.ndls_result"));
var span = resultDiv.FindElement(By.XPath(".//span[contains(text(),'전체')]"));
string text = span.Text; // 예: "전체 5 "
var match = System.Text.RegularExpressions.Regex.Match(text, @"전체\s*(\d+)");
if (match.Success)
{
return int.Parse(match.Groups[1].Value);
}
return 0;
}
catch
{
return 0;
}
}
// 페이지 변경을 감지하는 메서드
public async Task WaitForPageChange(WebDriverWait wait)
{
try
{
// 방법 4: 페이지 로딩 상태 확인
wait.Until(d =>
{
var readyState = ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState");
return readyState.Equals("complete");
});
// 방법 5: 특정 텍스트가 페이지에 나타날 때까지 대기
wait.Until(d =>
{
var pageText = d.FindElement(By.TagName("body")).Text;
return pageText.Contains("전체") || pageText.Contains("건") || pageText.Contains("검색결과");
});
}
catch (Exception ex)
{
// 모든 감지 방법이 실패하면 최소한의 대기 시간 적용
await Task.Delay(2000);
throw new Exception($"페이지 변경 감지 실패: {ex.Message}");
}
}
}
}

View File

@@ -0,0 +1,441 @@
using System;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System.Text.RegularExpressions;
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;
using System.IO;
using System.Runtime.InteropServices;
namespace BokBonCheck
{
public class NamguLibrarySearcher_Munhwa : NamguLibrarySearcher
{
public NamguLibrarySearcher_Munhwa(int no) : base(no)
{
SiteName = "남구통합도서관(문화정보도서관)"; // 문화관 검색기
}
protected override void SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == true)
{
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
}
else return;
selector = "#libMA";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == false)
{
searchBox.Click(); // 문화관 체크박스 선택
}
}
catch
{
}
}
}
public class NamguLibrarySearcher_Purungil : NamguLibrarySearcher
{
public NamguLibrarySearcher_Purungil(int no) : base(no)
{
SiteName = "남구통합도서관(푸른길도서관)";
}
protected override void SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == true)
{
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
}
else return;
selector = "#libMB";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == false)
{
searchBox.Click(); // 체크박스 선택
}
}
catch
{
}
}
}
public class NamguLibrarySearcher_Children : NamguLibrarySearcher
{
public NamguLibrarySearcher_Children(int no) : base(no)
{
SiteName = "남구통합도서관(청소년도서관)";
}
protected override void SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == true)
{
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
}
else return;
selector = "#libMC";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == false)
{
searchBox.Click(); // 체크박스 선택
}
}
catch
{
}
}
}
public class NamguLibrarySearcher_Hyocheon : NamguLibrarySearcher
{
public NamguLibrarySearcher_Hyocheon(int no) : base(no)
{
SiteName = "남구통합도서관(효천어울림도서관)";
}
protected override void SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == true)
{
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
}
else return;
selector = "#libSW";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == false)
{
searchBox.Click(); // 체크박스 선택
}
}
catch
{
}
}
}
public class NamguLibrarySearcher_Smart : NamguLibrarySearcher
{
public NamguLibrarySearcher_Smart(int no) : base(no)
{
SiteName = "남구통합도서관(스마트도서관)";
}
protected override void SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == true)
{
searchBox.Click(); // 전체체크박스가 체크되어 있으면 클릭해서 해제
}
else return;
selector = "#libSQ";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == false)
{
searchBox.Click(); // 체크박스 선택
}
}
catch
{
}
}
}
public class NamguLibrarySearcher : ILibrarySearcher
{
public string SiteName { get; protected set; } = "남구통합도서관(전체)";
public string SiteUrl => "https://lib.namgu.gwangju.kr/main/bookSearch";
public int No { get; set; }
private ChromeDriver _driver;
private ChromeDriverService _service;
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_MINIMIZE = 6;
public NamguLibrarySearcher(int no)
{
this.No = no;
}
public void StartDriver()
{
if (_driver == null)
{
var driverPath = ChromeDriverManager.GetDriverPath();
if (string.IsNullOrEmpty(driverPath) || !File.Exists(driverPath))
{
driverPath = ChromeDriverManager.SetupChromeDriverAsync().GetAwaiter().GetResult();
}
_service = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(driverPath), Path.GetFileName(driverPath));
_service.HideCommandPromptWindow = true;
var options = new ChromeOptions();
options.AddArgument("--no-sandbox");
options.AddArgument("--disable-dev-shm-usage");
options.AddArgument("--disable-gpu");
options.AddArgument("--window-size=1920,1080");
options.AddArgument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
options.AddArgument("--disable-blink-features=AutomationControlled");
options.AddExcludedArgument("enable-automation");
options.AddAdditionalOption("useAutomationExtension", false);
_driver = new ChromeDriver(_service, options);
((IJavaScriptExecutor)_driver).ExecuteScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
}
}
public void StopDriver()
{
if (_driver != null)
{
_driver.Quit();
_driver.Dispose();
_driver = null;
}
if (_service != null)
{
_service.Dispose();
_service = null;
}
}
virtual protected void SelectLibrary(WebDriverWait wait)
{
IWebElement searchBox = null;
try
{
var selector = "#clickAll";
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
if (searchBox != null && searchBox.Selected == false)
{
searchBox.Click(); // 전체체크박스가 해제되어 있으면 클릭해서 선택
}
else return;
}
catch
{
}
}
public async Task<BookSearchResult> SearchAsync(string searchTerm)
{
var result = new BookSearchResult
{
SiteName = SiteName,
SearchTerm = searchTerm,
SearchTime = DateTime.Now
};
try
{
if (_driver == null)
throw new InvalidOperationException("드라이버가 시작되지 않았습니다. StartDriver()를 먼저 호출하세요.");
_driver.Navigate().GoToUrl(SiteUrl);
// 페이지 로딩 대기
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
// 모든 감지 방법이 끝나면 크롬창 최소화
IntPtr chromeWindow = FindWindow("Chrome_WidgetWin_1", null);
if (chromeWindow != IntPtr.Zero)
{
ShowWindow(chromeWindow, SW_MINIMIZE);
}
//대상도서관 선택
SelectLibrary(wait);
// 검색창 찾기 (남구통합도서관 사이트의 특정 선택자 사용)
IWebElement searchBox = null;
try
{
// 여러 가능한 선택자 시도
var selectors = new[]
{
"input[name='query']",
"input[id='query']",
"input[type='text']",
};
foreach (var selector in selectors)
{
try
{
searchBox = wait.Until(d => d.FindElement(By.CssSelector(selector)));
break;
}
catch
{
continue;
}
}
if (searchBox == null)
{
throw new Exception("검색창을 찾을 수 없습니다.");
}
}
catch (Exception ex)
{
throw new Exception($"검색창 찾기 실패: {ex.Message}");
}
// 검색어 입력
searchBox.Clear();
searchBox.SendKeys(searchTerm);
// 검색 버튼 클릭
IWebElement searchButton = null;
try
{
var buttonSelectors = new[]
{
"button[type='submit']",
"input[type='submit']",
".search-btn",
".btn-search",
"button:contains('검색')",
"input[value*='검색']",
"button[class*='search']",
"input[class*='search']"
};
foreach (var selector in buttonSelectors)
{
try
{
searchButton = _driver.FindElement(By.CssSelector(selector));
break;
}
catch
{
continue;
}
}
if (searchButton == null)
{
// Enter 키로 검색 시도
searchBox.SendKeys(Keys.Enter);
}
else
{
searchButton.Click();
}
}
catch (Exception ex)
{
// Enter 키로 검색 시도
searchBox.SendKeys(Keys.Enter);
}
// 페이지 변경을 감지하는 메서드
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
// 검색 결과 수 추출
var resultCount = ExtractBookCount(_driver);
result.BookCount = resultCount;
result.IsSuccess = true;
}
catch (Exception ex)
{
result.IsSuccess = false;
result.ErrorMessage = ex.Message;
result.BookCount = 0;
}
return result;
}
private int ExtractBookCount(IWebDriver driver)
{
try
{
// div.search-result 내부의 span에서 '전체 N' 텍스트 추출
var resultDiv = driver.FindElement(By.CssSelector("div.search-result"));
var span = resultDiv.FindElement(By.XPath(".//span[contains(text(),'전체')]"));
string text = span.Text; // 예: "전체 5 "
var match = System.Text.RegularExpressions.Regex.Match(text, @"전체\s*(\d+)");
if (match.Success)
{
return int.Parse(match.Groups[1].Value);
}
return 0;
}
catch
{
return 0;
}
}
// 페이지 변경을 감지하는 메서드
public async Task WaitForPageChange(WebDriverWait wait)
{
try
{
// 방법 4: 페이지 로딩 상태 확인
wait.Until(d =>
{
var readyState = ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState");
return readyState.Equals("complete");
});
// 방법 5: 특정 텍스트가 페이지에 나타날 때까지 대기
wait.Until(d =>
{
var pageText = d.FindElement(By.TagName("body")).Text;
return pageText.Contains("전체") || pageText.Contains("건") || pageText.Contains("검색결과");
});
}
catch (Exception ex)
{
// 모든 감지 방법이 실패하면 최소한의 대기 시간 적용
await Task.Delay(2000);
throw new Exception($"페이지 변경 감지 실패: {ex.Message}");
}
}
}
}

View File

@@ -75,6 +75,9 @@
<ManifestKeyFile>UniMarc_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="AngleSharp, Version=1.0.4.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL">
<HintPath>..\packages\AngleSharp.1.0.4\lib\net472\AngleSharp.dll</HintPath>
</Reference>
<Reference Include="arCommUtil">
<HintPath>..\dll\arCommUtil.dll</HintPath>
</Reference>
@@ -87,19 +90,62 @@
<Reference Include="CarlosAg.ExcelXmlWriter">
<HintPath>..\dll\CarlosAg.ExcelXmlWriter.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=1.4.2.13, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.1.4.2\lib\netstandard2.0\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="Microsoft.Win32.Registry, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
</Reference>
<Reference Include="MySql.Data, Version=8.0.21.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL" />
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Renci.SshNet, Version=2020.0.1.0, Culture=neutral, PublicKeyToken=1cee9f8bde3db106, processorArchitecture=MSIL">
<HintPath>..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.DirectoryServices" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security.AccessControl, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.AccessControl.5.0.0\lib\net461\System.Security.AccessControl.dll</HintPath>
</Reference>
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
</Reference>
<Reference Include="System.ServiceModel" />
<Reference Include="System.Text.Encoding.CodePages, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encoding.CodePages.6.0.0\lib\net461\System.Text.Encoding.CodePages.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encodings.Web, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=7.0.0.3, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.7.0.3\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml.Linq" />
@@ -111,6 +157,15 @@
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="WebDriver, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Selenium.WebDriver.4.16.2\lib\netstandard2.0\WebDriver.dll</HintPath>
</Reference>
<Reference Include="WebDriver.Support, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Selenium.Support.4.16.2\lib\netstandard2.0\WebDriver.Support.dll</HintPath>
</Reference>
<Reference Include="WebDriverManager, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\WebDriverManager.2.17.1\lib\net462\WebDriverManager.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CExt.cs" />
@@ -125,6 +180,14 @@
<DependentUpon>Reference.svcmap</DependentUpon>
</Compile>
<Compile Include="CUtill.cs" />
<Compile Include="SearchModel\BookSearchService.cs" />
<Compile Include="SearchModel\ChromeDriverManager.cs" />
<Compile Include="SearchModel\DownloadProgressForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SearchModel\ILibrarySearcher.cs" />
<Compile Include="SearchModel\KwangjuCityLibrarySearcher.cs" />
<Compile Include="SearchModel\NamguLibrarySearcher.cs" />
<Compile Include="마스터\From_User_manage_List.cs">
<SubType>Form</SubType>
</Compile>
@@ -1868,4 +1931,11 @@
<Content Include="Resources\3_2_2_편목.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets" Condition="Exists('..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>이 프로젝트는 이 컴퓨터에 없는 NuGet 패키지를 참조합니다. 해당 패키지를 다운로드하려면 NuGet 패키지 복원을 사용하십시오. 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=322105를 참조하십시오. 누락된 파일은 {0}입니다.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Selenium.WebDriver.4.16.2\build\Selenium.WebDriver.targets'))" />
</Target>
</Project>

View File

@@ -9,6 +9,7 @@
<ErrorReportUrlHistory />
<FallbackCulture>ko-KR</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
<ProjectView>ProjectFiles</ProjectView>
</PropertyGroup>
<PropertyGroup>
<EnableSecurityDebugging>false</EnableSecurityDebugging>

View File

@@ -1,5 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
<package id="AngleSharp" version="1.0.4" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="7.0.0" targetFramework="net472" />
<package id="Microsoft.Win32.Registry" version="5.0.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
<package id="Selenium.Support" version="4.16.2" targetFramework="net472" />
<package id="Selenium.WebDriver" version="4.16.2" targetFramework="net472" />
<package id="SharpZipLib" version="1.4.2" targetFramework="net472" />
<package id="SSH.NET" version="2020.0.1" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
<package id="System.Security.AccessControl" version="5.0.0" targetFramework="net472" />
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net472" />
<package id="System.Text.Encoding.CodePages" version="6.0.0" targetFramework="net472" />
<package id="System.Text.Encodings.Web" version="7.0.0" targetFramework="net472" />
<package id="System.Text.Json" version="7.0.3" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
<package id="WebDriverManager" version="2.17.1" targetFramework="net472" />
</packages>

View File

@@ -36,6 +36,7 @@ namespace UniMarc.마크
this.lib_name = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Code = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.URL = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dvc_searcher = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
@@ -58,7 +59,8 @@ namespace UniMarc.마크
this.Area,
this.lib_name,
this.Code,
this.URL});
this.URL,
this.dvc_searcher});
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
@@ -105,6 +107,13 @@ namespace UniMarc.마크
this.URL.ReadOnly = true;
this.URL.Visible = false;
//
// dvc_searcher
//
this.dvc_searcher.HeaderText = "Searcher";
this.dvc_searcher.Name = "dvc_searcher";
this.dvc_searcher.ReadOnly = true;
this.dvc_searcher.Visible = false;
//
// Check_Copy_Sub_Search
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
@@ -126,5 +135,6 @@ namespace UniMarc.마크
private System.Windows.Forms.DataGridViewTextBoxColumn lib_name;
private System.Windows.Forms.DataGridViewTextBoxColumn Code;
private System.Windows.Forms.DataGridViewTextBoxColumn URL;
private System.Windows.Forms.DataGridViewTextBoxColumn dvc_searcher;
}
}

View File

@@ -26,15 +26,17 @@ namespace UniMarc.마크
this.Text = string.Format("검색어 : [{0}]", SearchText);
// Province, Area, lib_name, Code
string[] grid = { "", "", "", "", "" };
string[] grid = { "", "", "", "", "", "" };
for (int a = 0; a < ary.Length; a++)
{
if (a % 5 == 0) grid[0] = ary[a];
if (a % 5 == 1) grid[1] = ary[a];
if (a % 5 == 2) grid[2] = string.Format("{0}_{1}_{2}", grid[0], grid[1], ary[a]);
if (a % 5 == 3) grid[3] = ary[a];
if (a % 5 == 4) {
grid[4] = ary[a];
if (a % 6 == 0) grid[0] = ary[a];
if (a % 6 == 1) grid[1] = ary[a];
if (a % 6 == 2) grid[2] = string.Format("{0}_{1}_{2}", grid[0], grid[1], ary[a]);
if (a % 6 == 3) grid[3] = ary[a];
if (a % 6 == 4) grid[4] = ary[a];
if (a % 6 == 5)
{
grid[5] = ary[a];
dataGridView1.Rows.Add(grid);
}
}
@@ -73,6 +75,7 @@ namespace UniMarc.마크
string Code = dataGridView1.Rows[row].Cells["Code"].Value.ToString();
string URL = dataGridView1.Rows[row].Cells["URL"].Value.ToString();
string lib_name = dataGridView1.Rows[row].Cells["lib_name"].Value.ToString();
string searcher = dataGridView1.Rows[row].Cells["dvc_searcher"].Value.ToString();
string lib_Category = string.Format("{0}_{1}", Province, Area);
@@ -80,6 +83,7 @@ namespace UniMarc.마크
cc.Code = Code;
cc.URL = URL;
cc.tb_SearchTarget.Text = lib_name;
cc.SearcherNo = searcher;
if (lib_name.Contains("Kolasys.net"))
{

View File

@@ -132,4 +132,7 @@
<metadata name="URL.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="dvc_searcher.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@@ -28,7 +28,7 @@
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
this.panel1 = new System.Windows.Forms.Panel();
this.rb_isNumber = new System.Windows.Forms.RadioButton();
this.rb_isHave = new System.Windows.Forms.RadioButton();
@@ -39,7 +39,7 @@
this.btn_Close = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.tb_SearchTarget = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btSearchLibrary = new System.Windows.Forms.Button();
this.panel2 = new System.Windows.Forms.Panel();
this.btn_SiteDenote = new System.Windows.Forms.Button();
this.lbl_PW = new System.Windows.Forms.Label();
@@ -51,6 +51,8 @@
this.btn_ApplyFilter = new System.Windows.Forms.Button();
this.panel3 = new System.Windows.Forms.Panel();
this.panel6 = new System.Windows.Forms.Panel();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.lblStatus = new System.Windows.Forms.ToolStripLabel();
this.panel4 = new System.Windows.Forms.Panel();
this.chk_RemoveBrit = new System.Windows.Forms.CheckBox();
this.btn_ResultEmpty = new System.Windows.Forms.Button();
@@ -65,6 +67,7 @@
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.panel3.SuspendLayout();
this.panel6.SuspendLayout();
this.statusStrip1.SuspendLayout();
this.panel4.SuspendLayout();
this.panel5.SuspendLayout();
this.SuspendLayout();
@@ -176,14 +179,15 @@
this.tb_SearchTarget.TabIndex = 1;
this.tb_SearchTarget.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tb_SearchTarget_KeyDown);
//
// label1
// btSearchLibrary
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 10);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(53, 12);
this.label1.TabIndex = 0;
this.label1.Text = "검색대상";
this.btSearchLibrary.AutoSize = true;
this.btSearchLibrary.Location = new System.Drawing.Point(3, 5);
this.btSearchLibrary.Name = "btSearchLibrary";
this.btSearchLibrary.Size = new System.Drawing.Size(63, 23);
this.btSearchLibrary.TabIndex = 0;
this.btSearchLibrary.Text = "검색대상";
this.btSearchLibrary.Click += new System.EventHandler(this.btSearchLibrary_Click);
//
// panel2
//
@@ -193,7 +197,7 @@
this.panel2.Controls.Add(this.lbl_ID);
this.panel2.Controls.Add(this.SearchCount);
this.panel2.Controls.Add(this.tb_SearchTarget);
this.panel2.Controls.Add(this.label1);
this.panel2.Controls.Add(this.btSearchLibrary);
this.panel2.Controls.Add(this.btn_Close);
this.panel2.Controls.Add(this.label2);
this.panel2.Dock = System.Windows.Forms.DockStyle.Top;
@@ -236,14 +240,14 @@
this.dataGridView1.BackgroundColor = System.Drawing.SystemColors.Control;
this.dataGridView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.dataGridView1.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle2.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.book_name,
@@ -253,7 +257,7 @@
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowTemplate.Height = 23;
this.dataGridView1.Size = new System.Drawing.Size(629, 636);
this.dataGridView1.Size = new System.Drawing.Size(629, 614);
this.dataGridView1.TabIndex = 1;
this.dataGridView1.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(this.dataGridView1_RowPostPaint);
this.dataGridView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dataGridView1_KeyDown);
@@ -304,12 +308,29 @@
// panel6
//
this.panel6.Controls.Add(this.dataGridView1);
this.panel6.Controls.Add(this.statusStrip1);
this.panel6.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel6.Location = new System.Drawing.Point(0, 102);
this.panel6.Name = "panel6";
this.panel6.Size = new System.Drawing.Size(629, 636);
this.panel6.TabIndex = 3;
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.lblStatus});
this.statusStrip1.Location = new System.Drawing.Point(0, 614);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(629, 22);
this.statusStrip1.TabIndex = 2;
this.statusStrip1.Text = "statusStrip1";
//
// lblStatus
//
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(27, 20);
this.lblStatus.Text = "WD";
//
// panel4
//
this.panel4.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
@@ -413,6 +434,9 @@
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.panel3.ResumeLayout(false);
this.panel6.ResumeLayout(false);
this.panel6.PerformLayout();
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.panel4.ResumeLayout(false);
this.panel4.PerformLayout();
this.panel5.ResumeLayout(false);
@@ -423,7 +447,7 @@
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btSearchLibrary;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Button btn_Close;
@@ -452,5 +476,7 @@
public System.Windows.Forms.Label lbl_ID;
private System.Windows.Forms.Button btn_SiteDenote;
private System.Windows.Forms.WebBrowser webBrowser1;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripLabel lblStatus;
}
}

View File

@@ -6,6 +6,8 @@ using System.Text.RegularExpressions;
using System.Web;
using System.Windows.Forms;
using UniMarc.;
using BokBonCheck;
using AR;
namespace WindowsFormsApp1.Mac
{
@@ -15,6 +17,7 @@ namespace WindowsFormsApp1.Mac
public string URL;
public string lib_Category;
public string Code;
public string SearcherNo;
private bool isStop = false;
Main main;
public Check_copy(Main _main)
@@ -22,6 +25,20 @@ namespace WindowsFormsApp1.Mac
InitializeComponent();
main = _main;
db.DBcon();
//도서검색(크롤링)
_searchService = new BookSearchService();
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_central());
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_choisangjun());
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_dagachi());
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_Indi());
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_Student());
//_searchService.AddSearcher(new KwangjuCityLibrarySearcher_Kumho());
_searchService.AddSearcher(new NamguLibrarySearcher_Munhwa(1));
_searchService.AddSearcher(new NamguLibrarySearcher_Children(2));
_searchService.AddSearcher(new NamguLibrarySearcher_Smart(3));
_searchService.AddSearcher(new NamguLibrarySearcher_Purungil(4));
_searchService.AddSearcher(new NamguLibrarySearcher_Hyocheon(5));
}
private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
@@ -30,14 +47,119 @@ namespace WindowsFormsApp1.Mac
sg.Print_Grid_Num(sender, e);
}
private void Check_copy_Load(object sender, EventArgs e)
{
string[] Grid = { "----- 빈칸으로 놔주세요 -----", "빈칸", "" };
dataGridView1.Rows.Add(Grid);
this.Show();
Application.DoEvents();
//크롤링
InitializeChromeDriver();
}
#region
private readonly BookSearchService _searchService;
private bool _isSearching = false;
private bool _isDriverReady = false;
private async void InitializeChromeDriver()
{
var lblStatus = this.lblStatus;// (Label)this.Controls["lblStatus"];
lblStatus.Text = "WebDriver:Chrome 드라이버 확인 중...";
lblStatus.ForeColor = Color.Blue;
try
{
// Chrome 설치 확인
if (!ChromeDriverManager.IsChromeInstalled())
{
MessageBox.Show("Google Chrome이 설치되어 있지 않습니다. Chrome을 설치한 후 프로그램을 다시 실행해주세요.",
"Chrome 필요", MessageBoxButtons.OK, MessageBoxIcon.Warning);
lblStatus.Text = "WebDriver:Chrome이 설치되지 않음";
lblStatus.ForeColor = Color.Red;
return;
}
// 기존 드라이버가 준비되어 있는지 확인
if (ChromeDriverManager.IsDriverReady())
{
lblStatus.Text = "WebDriver:Ready";
lblStatus.ForeColor = Color.Green;
_isDriverReady = true;
return;
}
// 드라이버가 없거나 작동하지 않으면 다운로드 진행 창 표시
using (var progressForm = new DownloadProgressForm())
{
progressForm.Show();
try
{
// ChromeDriver 설정
await ChromeDriverManager.SetupChromeDriverAsync(progressForm);
// 드라이버 테스트
var isWorking = await ChromeDriverManager.TestChromeDriverAsync(progressForm);
if (isWorking)
{
_isDriverReady = true;
lblStatus.Text = "WebDriver:Ready";
lblStatus.ForeColor = Color.Green;
}
else
{
lblStatus.Text = "WebDriver:Chrome 드라이버 테스트 실패";
lblStatus.ForeColor = Color.Red;
MessageBox.Show("Chrome 드라이버 테스트에 실패했습니다. 인터넷 연결을 확인하고 프로그램을 다시 실행해주세요.",
"드라이버 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (OperationCanceledException)
{
lblStatus.Text = "WebDriver:드라이버 다운로드가 취소되었습니다.";
lblStatus.ForeColor = Color.Orange;
return;
}
catch (Exception ex)
{
lblStatus.Text = "WebDriver:Chrome 드라이버 설정 실패";
lblStatus.ForeColor = Color.Red;
MessageBox.Show($"Chrome 드라이버 설정 중 오류가 발생했습니다: {ex.Message}",
"설정 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
}
catch (Exception ex)
{
lblStatus.Text = "WebDriver:Chrome 드라이버 설정 실패";
lblStatus.ForeColor = Color.Red;
MessageBox.Show($"Chrome 드라이버 설정 중 오류가 발생했습니다: {ex.Message}",
"설정 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion
private void tb_SearchTarget_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
SearchLibrary();
}
}
void SearchLibrary()
{
string Target = tb_SearchTarget.Text;
// if (Target == "") { MessageBox.Show("도서관명이 비어있습니다."); return; }
string area = "`Province`, `Area`, `LibName`, `Code`, `URL`";
string area = "`Province`, `Area`, `LibName`, `Code`, `URL`, `SearcherNo`";
string cmd = string.Format("SELECT {0} FROM `lib_CopyCheck` WHERE CONCAT( province , '_' , AREA , '_' , libname) LIKE '%{1}%';", area, Target);
string data = db.self_Made_Cmd(cmd);
string[] ary = data.Split('|');
@@ -45,7 +167,6 @@ namespace WindowsFormsApp1.Mac
ccs.Init(ary, Target);
ccs.Show();
}
}
private void btn_SearchList_Click(object sender, EventArgs e)
{
@@ -61,17 +182,26 @@ namespace WindowsFormsApp1.Mac
SearchCount.Value = dataGridView1.Rows.Count;
}
private void btn_Start_Click(object sender, EventArgs e)
async private void btn_Start_Click(object sender, EventArgs e)
{
if (tb_SearchTarget.Text.Contains("Kolasys.net"))
var libraryName = tb_SearchTarget.Text.Trim();
if (libraryName.isEmpty())
{
tb_SearchTarget.Focus();
UTIL.MsgE("도서관을 선택하세요");
return;
}
if (libraryName.Contains("Kolasys.net"))
{
if (lbl_ID.Text == " " || lbl_PW.Text == " ")
{
MessageBox.Show("해당 도서관은 로그인정보가 필요합니다.\n복본조사 창을 껏다켜주세요.");
UTIL.MsgE("해당 도서관은 로그인정보가 필요합니다.\n복본조사 창을 껏다켜주세요.");
return;
}
}
isIksanClick = false;
isJBEClick = false;
isJNLClick = false;
@@ -85,10 +215,13 @@ namespace WindowsFormsApp1.Mac
dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0];
webBrowser1.Navigate("");
int SCount = Convert.ToInt32(SearchCount.Value);
if (SearcherNo.toInt() < 1)
{
//legacy
webBrowser1.Visible = true;
webBrowser1.Navigate("");
if (URL is null)
{
webBrowser1.DocumentCompleted -= this.webBrowser1_DocumentCompleted;
@@ -145,6 +278,105 @@ namespace WindowsFormsApp1.Mac
webBrowser1.DocumentCompleted += this.webBrowser1_DocumentCompleted;
return;
}
}
else
{
if(DateTime.Now > new DateTime(2025,08,31))
{
UTIL.MsgE("테스트 기간이 종료되었습니다\n개발자 문의 하세요");
return;
}
if (this._isDriverReady == false)
{
UTIL.MsgE("웹드라이버가 초기화되지 않았습니다\n1.크롬브라우즈가 설치되어있는지 확인하세요\n\n2.개발자 문의하세요");
return;
}
try
{
//chrome web driver
webBrowser1.Visible = false;
var searcher = this._searchService.Get(this.SearcherNo.toInt());
if (searcher == null)
{
UTIL.MsgE($"검색서비스가 존재하지 않습니다. 개발자에 문의 하세요\n검색서비스번호:{SearcherNo}");
return;
}
this._isSearching = true;
btn_Start.Enabled = false;
btn_Stop.Enabled = false;
searcher.StartDriver();
foreach (DataGridViewRow drow in this.dataGridView1.Rows)
{
if (this._isSearching == false)
{
drow.Cells["Count"].Value = "SKIP";
continue;
}
dataGridView1.CurrentCell = drow.Cells[0];
//var vBookName = drow.Cells["book_name"].Value;
var bookName = drow.Cells["book_name"].Value?.ToString() ?? string.Empty;
if (bookName.isEmpty())
{
drow.DefaultCellStyle.BackColor = Color.HotPink;
drow.DefaultCellStyle.ForeColor = Color.Blue;
continue;
}
var cntValue = drow.Cells["Count"].Value?.ToString() ?? string.Empty;
if (cntValue.Equals("SKIP"))
{
drow.DefaultCellStyle.BackColor = Color.LightSkyBlue;
drow.DefaultCellStyle.ForeColor = Color.Black;
continue;
}
var rlt = await searcher.SearchAsync(bookName);
if (rlt.IsSuccess)
{
drow.Cells["Count"].Value = $"{rlt.BookCount}";
if (rlt.BookCount == 0)
{
drow.DefaultCellStyle.BackColor = Color.LightGray;
drow.DefaultCellStyle.ForeColor = Color.Red;
}
else
{
drow.DefaultCellStyle.BackColor = Color.Yellow;
drow.DefaultCellStyle.ForeColor = Color.Blue;
}
}
else
{
drow.DefaultCellStyle.BackColor = Color.HotPink;
drow.DefaultCellStyle.ForeColor = Color.Blue;
}
}
searcher.StopDriver();
UTIL.MsgI("검색 완료");
}
catch (Exception ex)
{
UTIL.MsgE("Web Driver Error\n"+ex.Message);
}
finally
{
btn_Stop.Enabled = true;
btn_Start.Enabled = true;
this._isSearching = false;
}
}
}
int RowCount = 0;
@@ -195,7 +427,7 @@ namespace WindowsFormsApp1.Mac
break;
}
}
if(searchform != null)
if (searchform != null)
{
BookCount = ();
}
@@ -470,7 +702,7 @@ namespace WindowsFormsApp1.Mac
foreach (HtmlElement Btn in searchform.GetElementsByTagName("button"))
{
if (Btn.GetAttribute("type").IndexOf("submit") >-1)//.IndexOf("btn btn-search") > -1)
if (Btn.GetAttribute("type").IndexOf("submit") > -1)//.IndexOf("btn btn-search") > -1)
Btn.InvokeMember("click");
}
}
@@ -1348,6 +1580,7 @@ namespace WindowsFormsApp1.Mac
private void btn_Stop_Click(object sender, EventArgs e)
{
_isSearching = false;
webBrowser1.Stop();
webBrowser1.DocumentCompleted -= this.webBrowser1_DocumentCompleted;
}
@@ -1592,11 +1825,6 @@ namespace WindowsFormsApp1.Mac
this.Close();
}
private void Check_copy_Load(object sender, EventArgs e)
{
string[] Grid = { "----- 빈칸으로 놔주세요 -----", "빈칸", "" };
dataGridView1.Rows.Add(Grid);
}
private void Check_copy_FormClosing(object sender, FormClosingEventArgs e)
{
@@ -1607,15 +1835,12 @@ namespace WindowsFormsApp1.Mac
private void btn_SiteDenote_Click(object sender, EventArgs e)
{
if (URL == null) return;
try
{
System.Diagnostics.Process.Start(URL);
}
catch
{
AR.UTIL.RunExplorer(URL);
}
private void btSearchLibrary_Click(object sender, EventArgs e)
{
SearchLibrary();
}
}
}

View File

@@ -126,4 +126,7 @@
<metadata name="Count.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>