반응형

 

winform xUnit 단위 테스트 중 쿼리를 실행하는 메서드가 실행되지 않아서 삽질 끝에 해결했습니다.

 

1. Could not load file or assembly 'System.Data.SqlClient' 에러

 

~.sqlClient~(0.0.0.0) ~ 에러

 

xUnit 프로젝트에서 sqlClient 어셈블리 참조 시 바로 중단됨

 

구글링 결과 system.data.sqlClient 어셈블리를 Microsoft.data.sqlClient 으로 변경 후 해결된다 하여 system.data.sqlClient 제거 후 Nuget으로 Microsoft.data.sqlClient로 변경

단위테스트 실행했는데 잘 돌아가나 싶었으나 소수의 테스트만 통과를 못함

디버그 해보니 sqlConnectionstring 에서 예외 발생됨

이미 퇴근시간이 훌쩍 지나 포기하려 했으나 날린 시간이 아까워서 해결하고 가기로 마음먹음

Microsoft.data.sqlClient 로 변경 후 xUnit에서 어셈블리 참조는 되지만

sqlConnectionstring 에서 계속 다른 예외 발생

 

 

 

2. Microsoft.data.sqlClient로 변경 후, DB 연결 에러(신뢰되지 않은 기관에서 인증 체인을 발급했습니다) 

 

혹시나 해서 winform앱을 실행하니 DB인증 에러 발생.

이제는 xUnit도 안되고 winform앱도 DB 연결이 불가능해짐.

그래도 관련 자료가 있어 금방 해결됨

sqlConnectionString에 {server=..~~..~..};TrustServerCertificate=True; 추가하니 DB 인증에러 해결됨

다시 테스트 돌렸으나 1번 해결 후 상황과 같음 xUnit에서는 여전히 안됨 

 

3. xUnit 프로젝트에 Microsoft.data.sqlClient 참조

 

2번 에러 해결 후  1번 에러에서 버전이 4.0.0.0으로 변경되고

똑같이 sqlConnectionString에서 예외 발생됨

(tryExecption ~ 이런걸로 내용이 조금 바뀌어 있었는데 기억하기 싫음)

단위 테스트 프로젝트에도 1번에서와 같이 Nuget으로 Microsoft.data.sqlClient 설치 후 해결

 

 

결론

1. system.data.sqlClient 제거 

2. 어플리케이션, 단위테스트 프로젝트에 각각 Microsoft.data.sqlClient 설치 

3. DB 인증 에러 발생시 TrustServerCertificate=True 추가

 

 

Microsoft.data.sqlClient 로 변경 후 다른 문제 있으면 추가로 업데이트 예정.

 

 

반응형
반응형

 

타이머를 이용해서 간단하게 구현할수 있습니다.

 

유저에게 필수 입력 항목을 강조할때 사용했습니다.

 

1) 코드 예제

 

이해가 안되시면 코드전체를 긁어서 사용하시면 됩니다.

 private Timer mBlinkTimer = new Timer();
       private bool mStart = false;
​
       public Form1()
       {
           InitializeComponent();
       }
​
       Button btnBlink;
       Button btnRun;
​
       private void Form1_Load(object sender, EventArgs e)
       {
           this.Size = new Size(1000, 500);
​
           btnBlink = new Button();
           btnBlink.Size = new Size(300, 300);
           btnBlink.Location = new Point((this.Width - btnBlink.Size.Width) / 2, (this.Height - btnBlink.Size.Height) / 2);
           this.Controls.Add(btnBlink);
​
           btnRun = new Button();
           btnRun.Text = "Start/Stop";
           btnRun.Size = new Size(100, 0);
           btnRun.Dock = DockStyle.Right;
           this.Controls.Add(btnRun);
​
           btnRun.Click += btnRun_Click;
​
           mBlinkTimer.Interval = 500;
           mBlinkTimer.Tick += BlinkTimer_Tick;
​
           btnBlink.BackColor = Color.Gainsboro;
       }
​
       private void BlinkTimer_Tick(object sender, EventArgs e)
       {
           if (mStart)
           {
               if (btnBlink.BackColor == Color.Gainsboro)
               {
                   btnBlink.BackColor = Color.Yellow;
               }
               else
               {
                   btnBlink.BackColor = Color.Gainsboro;
               }
           }
       }
​
       private void btnRun_Click(object sender, EventArgs e)
       {
           mBlinkTimer.Enabled = !mStart;
           mStart = !mStart;
       }

Timer Interval에 반짝일 속도를 설정하고 

Timer Tick 이벤트에서

멤버 변수인 불린 start가 true 일때만 반짝이게 하는 코드입니다.

 

 

 

2) 결과

 

반응형
반응형

 

 

1. 코드 예시

​
       private DataTable CreateDataTable()
       {
           DataTable dt = new DataTable();
​
           dt.Columns.Add("NUM", typeof(int));
           dt.Columns.Add("NAME", typeof(string));
           dt.Columns.Add("DESC", typeof(string));
​
           for(int i=1; i <= 10; i++)
           {
               var dr = dt.NewRow();
​
               dr["NUM"] = i;
               dr["NAME"] = i % 2 == 0 ? "이름" : null;
               dr["DESC"] = "";
​
               dt.Rows.Add(dr);
           }
​
           return dt;
       }
       
       private void Form1_Load(object sender, EventArgs e)
       {
           gridControl1.DataSource = CreateDataTable();
​
           gridView1.Columns["NAME"].ShowButtonMode = DevExpress.XtraGrid.Views.Base.ShowButtonModeEnum.ShowAlways;
       }
​
     
​
       private void gridView1_CustomRowCellEdit(object sender, DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs e)
       {
           RepositoryItemButtonEdit rbtnEdit = new RepositoryItemButtonEdit();
​
           if(e.Column.FieldName == "NAME")
           {
               if(e.CellValue.ToString() == "")
               {
                   e.RepositoryItem = rbtnEdit;
               }
           }
       }

 

CustomRowCellEdit 이벤트에서 표시하고 싶은 셀에 조건을 두어 RepositoryItem에 버튼을 추가한다.

 

 

 

2. 실행 결과

 

반응형
반응형

 

C# 디렉토리 파일 구분 방법

 

사내 시스템에서 사용자가 파일 업로드 시

 

업로드 파일을 압축해서 보관하다가 압축파일 다운 후 압축을 해제하도록 했는데

 

사용자가 USB STICK을 사용하다 보니 압축 해제 속도가 나오지 않아서

 

그냥 폴더 상태로 보관하도록 루틴을 변경했다.

 

그러다보니 기존 ZIP파일일때와 폴더일때 구분이 필요하게 되었다.

 

 

            string path = "Selected Path";

            FileAttributes attr = File.GetAttributes(path);
            if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
            {
                //디렉토리(폴더)
            }
            else
            {
                //파일
            }
반응형
반응형

 

 

C# 숨김 폴더 체크 방법

이번 작업 중에 이동식 드라이브를 연결하면

 

모든 디렉토리와 파일을 삭제해야하는데

 

이동식 드라이브 내부에 두가지 숨겨진 폴더가 있어서

 

예외처리가 필요했다.

 

 

숨김폴더 체크 예제

using System.IO;

            string path = "D:\\";

            DirectoryInfo dir = new DirectoryInfo(path);

            if((dir.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
            {
                Console.WriteLine("숨김 폴더");
            }

 

저는 디렉토리 &파일 삭제 재귀 함수에

 

Hidden 이면 예외처리하게 사용

 

 

 

반응형
반응형

최근 압축 및 압축해제를 구현해야해서 라이브러리를 찾아보던 중

IONIC.ZIP 라이브러리를 사용하게 되었습니다.

 

설치는 비주얼스튜디오 NuGet에서 Ionic으로 검색하면 설치할 수 있습니다.

 

예제는 선택한 폴더를 압축/압축해제 하는 예제 코드 입니다.

 

1. 압축

        private void zipFolder()
        {
            string sSourcePath = tbLoadFolderPath.Text;
            string sTargetPath = tbSavePath.Text;

            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    DirectoryInfo di = new DirectoryInfo(sSourcePath);
                    //프로그레스바 최대 값 (디렉토리내 모든 파일 수)
                    mMaximum += di.GetFiles("*.*", System.IO.SearchOption.AllDirectories).Count();

                    //프로그레스바 이벤트 설정
                    zip.SaveProgress += Zip_SaveProgress;


                    FileInfo[] infos = di.GetFiles("*.*", SearchOption.AllDirectories);

                    string[] files = new string[infos.Length];

                    for (int i = 0; i < infos.Length; i++)
                    {
                        files[i] = infos[i].FullName;
                    }

                    byte[] b = null;
                    string fileName = string.Empty;

                    foreach (string file in files)
                    {
                        fileName = file.Replace(sSourcePath, "");

                        //기본 인코딩 타입으로 읽기
                        b = Encoding.Default.GetBytes(fileName);

                        // IBM437로 변환
                        fileName = Encoding.GetEncoding("IBM437").GetString(b);

                        zip.AddEntry(fileName, File.ReadAllBytes(file));
                    }

                    DirectoryInfo dir = new DirectoryInfo(sTargetPath);

                    if(!dir.Exists)
                    {
                        dir.Create();
                    }

                    string[] split = sSourcePath.Split('\\');

                    string sZipName = split[split.Length - 1];

                    zip.Save($"{sTargetPath}\\{sZipName}.zip");
                }
                Process.Start(sTargetPath);
            }
            catch(Exception ex)
            {
                MessageBox.Show($"{ex.Message}\r\n압축 실패");
                return;
            }
        }

 

2. 압축 해제

 

       private void unZipFile()
        {
            string sSourcePath = tbLoadZipPath.Text;
            string sTargetPath = tbSavePath.Text;

            try
            {
                using (ZipFile zip = ZipFile.Read(sSourcePath))
                {
                    FileInfo fi = new FileInfo(sSourcePath);

                    zip.ExtractProgress += Extract_Progress;

                    //프로그레스바 맥시멈 값
                    mMaximum = zip.Entries.Count;

                    DirectoryInfo dir = new DirectoryInfo(sTargetPath);

                    if (!dir.Exists)
                    {
                        dir.Create();
                    }

                    string saveFolderPath = $"{sTargetPath}\\{Path.GetFileNameWithoutExtension(sSourcePath)}";

                    for (int i = 0; i < zip.Entries.Count; i++)
                    {
                        ZipEntry entry = zip[i];

                        //IBM437 인코딩
                        byte[] byteIbm437 = Encoding.GetEncoding("IBM437").GetBytes(zip[i].FileName);
                        //euckr 인코딩
                        string euckrFileName = Encoding.GetEncoding("euc-kr").GetString(byteIbm437);

                        zip[i].FileName = euckrFileName;

                        entry.Extract(saveFolderPath, ExtractExistingFileAction.OverwriteSilently);
                    }
                    Process.Start(saveFolderPath);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"{ex.Message}\r\n압축 해제 실패");
                return;
            }
        }

 

 

3. 예제 소스 코드 파일

 

 

 

 

 

 

 

 

 

 

 

 

WindowsFormsApp3.zip
0.86MB

프로그레스바를 ionic.zip에서 지원하는 이벤트로만 구현했는데

개인적으로 사용하실때에는 조금 손보는게 좋을 것 같습니다.

 

예제 코드는 이전에 구글링한 자료에 집에서 생각나는것만 정리한 정도이니 참고만 하시면 될 것 같습니다

 

 

 

반응형
반응형



Visual Studio 2015 다운로드 및 설치 방법 입니다.


2010 을 주로사용하긴 하는데


다시 C언어 기초부터 공부해보자 해서 오랜만에 책을 꺼내들고 설치ㅠㅠ





먼저 설치파일을 다운받으러 가봅시다.


https://www.visualstudio.com/ko/downloads/







Free Dowonload 클릭!


제가 링크건 홈페이지로 가시면 한글로 표시되실겁니다


무료 다운로드 클릭!






저는 브라우저를 크롬을 사용하기 때문에


하단에 설치파일이 다운로드 되었네요


다운로드 완료된 설치파일을 실행 해줍니다.



실행 눌러주세요~



실행하시면 


Visual Studio 2015의 설치가 시작 됩니다.




이런창으로 변경되면 Custom을 눌러주세요



보통 목적은 C와 C++ 이기 때문에 


Visual C++ 에 Check 하시고,


Next 버튼을 클릭 합니다.




설치 준비가 완료 되었습니다.


Install 버튼을 클릭 합니다.



설치 진행 중 입니다.


시간이 은근 많이 소요되기 때문에,


잠깐 딴짓 좀 합니다..





생각보다 꽤나 오래걸렸지만


Setup Completed!!


Restart Now 버튼을 눌러 컴퓨터 재부팅을 실시 하시면 설치 완료!!



이제 C언어 부터 차근차근 시작하면서 공부를 시작..!!


이상입니다.



반응형

+ Recent posts