using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Text.RegularExpressions; using System.Net; namespace UpdateInfoMaker { public partial class Form1 : Form { private string currentIniPath = ""; private Dictionary> iniData = new Dictionary>(); private List fileList = new List(); private string configFilePath = Path.Combine(Application.StartupPath, "config.ini"); public Form1() { InitializeComponent(); LoadSettings(); } private void btRead_Click(object sender, EventArgs e) { using (var od = new OpenFileDialog()) { od.Filter = "inf file|*.inf|All files|*.*"; if (od.ShowDialog() == DialogResult.OK) { //ini 파일을 읽어서 텍스트박스에 표시 currentIniPath = od.FileName; ReadIniFile(currentIniPath); UpdateUIFromIniData(); } } } private void btWrite_Click(object sender, EventArgs e) { using (var od = new SaveFileDialog()) { od.Filter = "inf file|*.inf|All files|*.*"; if (od.ShowDialog() == DialogResult.OK) { //ini 파일을 다시 생성한다 UpdateIniDataFromUI(); WriteIniFile(od.FileName); MessageBox.Show("INI 파일이 성공적으로 저장되었습니다.", "저장 완료", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } private void btUpdateFilelist_Click(object sender, EventArgs e) { //read에서 읽은 파일으 폴더내에서 exe,dll,xml,config 파일목록을 읽어서 목록을 구성한다 if (string.IsNullOrEmpty(currentIniPath)) { MessageBox.Show("먼저 INF 파일을 읽어주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } string folderPath = Path.GetDirectoryName(currentIniPath); UpdateFileList(folderPath); UpdateFileListView(); SaveSettings(); } private void ReadIniFile(string filePath) { iniData.Clear(); fileList.Clear(); if (!File.Exists(filePath)) return; string[] lines = File.ReadAllLines(filePath, Encoding.Default); string currentSection = ""; foreach (string line in lines) { string trimmedLine = line.Trim(); if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith(";")) continue; if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]")) { currentSection = trimmedLine.Substring(1, trimmedLine.Length - 2); if (!iniData.ContainsKey(currentSection)) iniData[currentSection] = new Dictionary(); } else if (!string.IsNullOrEmpty(currentSection) && trimmedLine.Contains("=")) { int equalIndex = trimmedLine.IndexOf('='); string key = trimmedLine.Substring(0, equalIndex).Trim(); string value = trimmedLine.Substring(equalIndex + 1).Trim(); if (currentSection == "files" && key == "Files") { iniData[currentSection][key] = value; } else if (currentSection == "files" && !key.StartsWith("\\")) { // 파일 목록 항목 fileList.Add(trimmedLine); } else { iniData[currentSection][key] = value; } } else if (currentSection == "files" && trimmedLine.StartsWith("\\")) { fileList.Add(trimmedLine); } } } private void WriteIniFile(string filePath) { var lines = new List(); // Version 섹션 if (iniData.ContainsKey("Version")) { lines.Add("[Version]"); foreach (var kvp in iniData["Version"]) { lines.Add($"{kvp.Key}={kvp.Value}"); } lines.Add(""); } // program_info 섹션 if (iniData.ContainsKey("program_info")) { lines.Add("[program_info]"); foreach (var kvp in iniData["program_info"]) { lines.Add($"{kvp.Key}={kvp.Value}"); } lines.Add(""); } // files 섹션 if (iniData.ContainsKey("files")) { lines.Add("[files]"); if (iniData["files"].ContainsKey("Files")) { lines.Add($"Files={fileList.Count}"); } foreach (string file in fileList) { lines.Add(file); } lines.Add("[NoteEndLine]"); } File.WriteAllLines(filePath, lines, Encoding.Default); } private void UpdateUIFromIniData() { if (iniData.ContainsKey("Version")) { if (iniData["Version"].ContainsKey("count")) tbCount.Text = iniData["Version"]["count"]; if (iniData["Version"].ContainsKey("date")) tbDate.Text = iniData["Version"]["date"]; } if (iniData.ContainsKey("program_info")) { if (iniData["program_info"].ContainsKey("server_url")) tbServerURL.Text = iniData["program_info"]["server_url"]; if (iniData["program_info"].ContainsKey("exe")) tbExeFileName.Text = iniData["program_info"]["exe"]; } UpdateFileListView(); } private void UpdateIniDataFromUI() { // Version 섹션 업데이트 if (!iniData.ContainsKey("Version")) iniData["Version"] = new Dictionary(); iniData["Version"]["count"] = tbCount.Text; iniData["Version"]["date"] = tbDate.Text; // program_info 섹션 업데이트 if (!iniData.ContainsKey("program_info")) iniData["program_info"] = new Dictionary(); iniData["program_info"]["server_url"] = tbServerURL.Text; iniData["program_info"]["exe"] = tbExeFileName.Text; // files 섹션 업데이트 if (!iniData.ContainsKey("files")) iniData["files"] = new Dictionary(); iniData["files"]["Files"] = fileList.Count.ToString(); } private void UpdateFileList(string folderPath) { fileList.Clear(); if (!Directory.Exists(folderPath)) return; string[] extensions = { "*.inf","*.exe", "*.dll", "*.xml", "*.config" }; // 제외할 파일 목록 가져오기 HashSet exceptFiles = GetExceptFiles(); foreach (string extension in extensions) { string[] files = Directory.GetFiles(folderPath, extension, SearchOption.TopDirectoryOnly); foreach (string file in files) { string fileName = Path.GetFileName(file); // 제외 파일 목록에 없는 경우에만 추가 if (!exceptFiles.Contains(fileName)) { fileList.Add($"\\{fileName}"); } } } // 파일 개수 업데이트 if (!iniData.ContainsKey("files")) iniData["files"] = new Dictionary(); iniData["files"]["Files"] = fileList.Count.ToString(); } private void UpdateFileListView() { listView1.Items.Clear(); foreach (string file in fileList) { string fileName = file.TrimStart('\\'); string filePath = Path.Combine(Path.GetDirectoryName(currentIniPath), fileName); var item = new ListViewItem(fileName); if (File.Exists(filePath)) { FileInfo fileInfo = new FileInfo(filePath); item.SubItems.Add(FormatFileSize(fileInfo.Length)); } else { item.SubItems.Add("X"); } listView1.Items.Add(item); } } private string FormatFileSize(long bytes) { string[] sizes = { "B", "KB", "MB", "GB" }; double len = bytes; int order = 0; while (len >= 1024 && order < sizes.Length - 1) { order++; len = len / 1024; } return $"{len:0.##} {sizes[order]}"; } private HashSet GetExceptFiles() { var exceptFiles = new HashSet(StringComparer.OrdinalIgnoreCase); if (!string.IsNullOrWhiteSpace(tbExceptfile.Text)) { string[] files = tbExceptfile.Text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string file in files) { exceptFiles.Add(file.Trim()); } } return exceptFiles; } private void LoadSettings() { try { if (File.Exists(configFilePath)) { string[] lines = File.ReadAllLines(configFilePath, Encoding.Default); foreach (string line in lines) { if (line.StartsWith("exceptfiles=")) { tbExceptfile.Text = line.Substring("exceptfiles=".Length); break; } } } else { // 기본값 설정 tbExceptfile.Text = "Factory_Client.exe"; SaveSettings(); } } catch (Exception ex) { MessageBox.Show($"설정 파일 로드 중 오류가 발생했습니다: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error); tbExceptfile.Text = "Factory_Client.exe"; } } private void SaveSettings() { try { string[] lines = { $"exceptfiles={tbExceptfile.Text}" }; File.WriteAllLines(configFilePath, lines, Encoding.Default); } catch (Exception ex) { MessageBox.Show($"설정 파일 저장 중 오류가 발생했습니다: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void tbUploadFile_Click(object sender, EventArgs e) { //파일목록의 파일을 지정된 FTP정보를 가지고 업로드해야함 UploadFilesToFTP(); } private void UploadFilesToFTP() { // FTP 정보 유효성 검사 if (string.IsNullOrWhiteSpace(tbFTPServer.Text) || string.IsNullOrWhiteSpace(tbFTPId.Text) || string.IsNullOrWhiteSpace(tbFTPPW.Text)) { MessageBox.Show("FTP 서버, 아이디, 패스워드를 모두 입력해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } if (fileList.Count == 0) { MessageBox.Show("업로드할 파일이 없습니다. 먼저 파일 목록을 업데이트해주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } if (string.IsNullOrEmpty(currentIniPath)) { MessageBox.Show("먼저 INF 파일을 읽어주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } try { string sourceFolder = Path.GetDirectoryName(currentIniPath); string ftpServer = tbFTPServer.Text.Trim(); string ftpUser = tbFTPId.Text.Trim(); string ftpPassword = tbFTPPW.Text.Trim(); string ftpPath = tbFTPPath.Text.Trim(); int ftpPort = 21; if (!int.TryParse(tbFTPPort.Text, out ftpPort)) { ftpPort = 21; } int successCount = 0; int failCount = 0; var failedFiles = new List(); foreach (string file in fileList) { string fileName = file.TrimStart('\\'); string localFilePath = Path.Combine(sourceFolder, fileName); if (!File.Exists(localFilePath)) { failedFiles.Add($"{fileName} (파일 없음)"); failCount++; continue; } try { // FTP URI 생성 string ftpUri; if (ftpPath.EndsWith("/")) ftpUri = $"ftp://{ftpServer}:{ftpPort}{ftpPath}{fileName}"; else ftpUri = $"ftp://{ftpServer}:{ftpPort}{ftpPath}/{fileName}"; FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUri); request.Method = WebRequestMethods.Ftp.UploadFile; request.Credentials = new NetworkCredential(ftpUser, ftpPassword); request.UsePassive = chkFTPPassive.Checked; request.UseBinary = true; request.KeepAlive = false; // 파일 업로드 using (FileStream fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read)) using (Stream ftpStream = request.GetRequestStream()) { byte[] buffer = new byte[10240]; int read; while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0) { ftpStream.Write(buffer, 0, read); } } // 응답 확인 using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) { if (response.StatusCode == FtpStatusCode.ClosingData || response.StatusCode == FtpStatusCode.FileActionOK) { successCount++; } else { failedFiles.Add($"{fileName} (상태: {response.StatusDescription})"); failCount++; } } } catch (Exception ex) { failedFiles.Add($"{fileName} ({ex.Message})"); failCount++; } } // 결과 메시지 표시 string resultMessage = $"업로드 완료\n\n성공: {successCount}개\n실패: {failCount}개"; if (failedFiles.Count > 0) { resultMessage += "\n\n실패한 파일들:\n" + string.Join("\n", failedFiles); } MessageBox.Show(resultMessage, "FTP 업로드 결과", MessageBoxButtons.OK, failCount > 0 ? MessageBoxIcon.Warning : MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show($"FTP 업로드 중 오류가 발생했습니다: {ex.Message}", "오류", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }