using DevExpress.Internal.WinApi.Windows.UI.Notifications; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Data.SqlClient; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Security.Policy; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace SystemX.Product.CP.RecoveryTool { public partial class Form1 : Form { string mdfFile = string.Empty; string ldfFile = string.Empty; string recoveryName = string.Empty; public Form1() { InitializeComponent(); SelectDBList(); lbAttachResult.Text = string.Empty; } private void btnSelectDb_Click(object sender, EventArgs e) { mdfFile = string.Empty; ldfFile = string.Empty; recoveryName = string.Empty; textRecoveryName.Text = string.Empty; using (OpenFileDialog dialog = new OpenFileDialog()) { dialog.Filter = "*.mdf|*.mdf"; if (dialog.ShowDialog() == DialogResult.OK) { mdfFile = dialog.FileName; string ldfName = $"{Path.GetFileNameWithoutExtension(dialog.FileName)}_log.ldf"; ldfFile = $@"{Path.GetDirectoryName(dialog.FileName)}\{ldfName}"; } textMdf.Text = mdfFile; //mdf textLdf.Text = ldfFile; //ldf textRecoveryName.Text = Path.GetFileNameWithoutExtension(textMdf.Text); } } private void btnAttach_Click(object sender, EventArgs e) { string error = "success"; DialogResult result = MessageBox.Show( $"Attach DB Name: '{textRecoveryName.Text}_Recovery' 연결 하시겠습니까?", // 메시지 내용 "Attach DB", // 타이틀 MessageBoxButtons.YesNo, // 버튼 옵션 MessageBoxIcon.Question // 아이콘 (선택 사항) ); if(result == DialogResult.Yes) { if (File.Exists(mdfFile) == true) ledMdf.BackColor = Color.Lime; else { ledMdf.BackColor = Color.Red; error = "Invalid Mdf File"; } if (File.Exists(ldfFile) == true) ledLdf.BackColor = Color.Lime; else { ledLdf.BackColor = Color.Red; error = "Invalid Ldf File"; } recoveryName = textRecoveryName.Text; if (string.IsNullOrEmpty(recoveryName) == false) ledLdf.BackColor = Color.Lime; else { ledLdf.BackColor = Color.Red; error = "Invalid RecoveryName"; } lbAttachResult.Text = error; if (error == "success") { string attachError = Attach(mdfFile, ldfFile, recoveryName); if (string.IsNullOrEmpty(attachError) == false) { lbAttachResult.ForeColor = Color.Red; lbAttachResult.Text = attachError; } else lbAttachResult.ForeColor = Color.Lime; } else lbAttachResult.ForeColor = Color.Red; SelectDBList(); } } private string Attach(string mdfFile, string ldfFile, string attachName) { string error = string.Empty; // 프로세스 설정 string command = $" -S localhost -U alis -P Kefico!@34 -Q \"CREATE DATABASE {attachName}_Recovery ON (FILENAME = '{mdfFile}'), (FILENAME = '{ldfFile}') FOR ATTACH;\""; Console.WriteLine(command); ProcessStartInfo startInfo = new ProcessStartInfo { FileName = $"sqlcmd", // cmd.exe로 명령어 실행 Arguments = $"{command}", // /c는 명령어 실행 후 종료하는 옵션 RedirectStandardOutput = true, // 표준 출력 리디렉션 RedirectStandardError = true, // 표준 오류 리디렉션 UseShellExecute = false, // 셸을 사용하지 않도록 설정 CreateNoWindow = true // 새 창을 열지 않도록 설정, }; // 프로세스 실행 using (Process process = Process.Start(startInfo)) { if (process != null) { // 출력 결과를 읽기 string output = process.StandardOutput.ReadToEnd(); string response = process.StandardError.ReadToEnd(); Console.WriteLine(output); Console.WriteLine(response); error = output; } } return error; } private void Detach(string dbName) { // 프로세스 설정 string command = $" -S localhost -U alis -P Kefico!@34 -Q \"ALTER DATABASE [{dbName}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; EXEC sp_detach_db '{dbName}';\""; Console.WriteLine(command); ProcessStartInfo startInfo = new ProcessStartInfo { FileName = $"sqlcmd", // cmd.exe로 명령어 실행 Arguments = $"{command}", // /c는 명령어 실행 후 종료하는 옵션 RedirectStandardOutput = true, // 표준 출력 리디렉션 RedirectStandardError = true, // 표준 오류 리디렉션 UseShellExecute = false, // 셸을 사용하지 않도록 설정 CreateNoWindow = true // 새 창을 열지 않도록 설정, }; // 프로세스 실행 using (Process process = Process.Start(startInfo)) { if (process != null) { // 출력 결과를 읽기 string output = process.StandardOutput.ReadToEnd(); string response = process.StandardError.ReadToEnd(); Console.WriteLine(output); Console.WriteLine(response); } } } private void SelectDBList() { //delay DateTime start = DateTime.Now; while(true) { if (DateTime.Now - start >= TimeSpan.FromMilliseconds(1000)) break; Thread.Sleep(10); } gridDB.Rows.Clear(); var connMain = new SqlConnection("server=127.0.0.1,1433;uid=alis;password=Kefico!@34;"); connMain.Open(); SqlCommand SQLCmd = new SqlCommand("select name from sys.databases with(nolock) where owner_sid != 0x01 and name like '%Recovery%';", connMain); SQLCmd.CommandType = CommandType.Text; DbDataReader dtReader = SQLCmd.ExecuteReader(); DataTable dtResult = new DataTable(); dtResult.Load(dtReader); List list = dtResult?.AsEnumerable()?.Select(x => x.ItemArray?.First()?.ToString())?.ToList(); foreach(var db in list) { gridDB.Rows.Add(gridDB.Rows.Count + 1, db, "Remove"); } } private void gridDB_CellContentClick(object sender, DataGridViewCellEventArgs e) { //remove button if (e.ColumnIndex == 2) { var dbName = gridDB.Rows[e.RowIndex].Cells[1].Value.ToString(); DialogResult result = MessageBox.Show( $"Attach DB Name: '{dbName}' 연결을 삭제 하시겠습니까?", // 메시지 내용 "Detach DB", // 타이틀 MessageBoxButtons.YesNo, // 버튼 옵션 MessageBoxIcon.Question // 아이콘 (선택 사항) ); if(result == DialogResult.Yes) { Detach(dbName); SelectDBList(); } } } private void btnRefresh_Click(object sender, EventArgs e) { SelectDBList(); } } }