COM 객체와 닷넷의 가바지 컬렉션이 궁합이 맞지않아 프로세스가 종료되지 않는 현상이 자주 발생한다.

 

엑셀COM 프로세스가 종료되려면 Application, WorkBook, WorkSheet 등이 해제(release)되어야된다.

 

       
        Microsoft.Office.Interop.Excel.Workbook pWorkbook = null;
        Microsoft.Office.Interop.Excel.Sheets pWorkSheets = null;
        Microsoft.Office.Interop.Excel.Worksheet pWorkSheet = null;
       
        m_ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();

        // 엑셀 내용 Start
                      º
                      º
                      º  
                      º
                      º
        // 엑셀 내용 End
        
        pWorkbook.Save();

        releaseObject(m_ExcelApp);
        releaseObject(pWorkSheet);
        releaseObject(pWorkSheets);
        releaseObject(pWorkbook);

        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();


        private static void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception e)
            {
                obj = null;
            }
            finally
            {
                GC.Collect();
            }
        }


 

만약 Release 했는데도 EXCEL.EXE가 프로세스에 남아있다면 PID를 찾아 프로세스를 kill해주면 된다.

다음글에 작성...

업무중에 갑자기 LOG를 찍어봐야할때 간단하게 txt파일로 만들어 확인할 수 있는 코드 

 

            string Fpath = @"C:\temp\새폴더\LOG.txt"; // 파일 경로 
            DirectoryInfo dif = new DirectoryInfo(@"C:\temp\새폴더"); // 디렉토리 경로

            if (!dif.Exists) // 디렉토리 체크
            {
                dif.Create();
            }

            FileInfo file = new FileInfo(Fpath); // 파일 체크 후 생성
            if (!file.Exists)
            {
                FileStream fs = file.Create();
                fs.Close();
            }

            File.AppendAllText(Fpath, "LOG 메세지");   // 시간추가 DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:")

이렇게 크로스 쓰레드 에러가 날 경우 해결방법

 

public void Select()
        {
            for (int i = 0; i < 2; i++)
            {
                cnt = i.ToString();
                CrossThread(tb1, cnt); 

                Thread.Sleep(3000);

            }
        }

public static void CrossThread(Control ctrl, string text)
        {
            if (ctrl.InvokeRequired)
            {
                ctrl.BeginInvoke(new MethodInvoker(delegate ()
                {
                    ctrl.Text += text;
                }));
            }
        }

이런식으로 호출할경우 해결된다.

DataSet을 만들고 DataTable을 생성하여

해당 디렉토리에 있는 파일 데이터( 이름, 형식, 수정날짜, 크기 )를 넣고 

DataGridView에 출력해보겠습니다.

 

DataSet ds = new DataSet();

 

        private void btnSearch_Click_1(object sender, EventArgs e)
        {
            bool bCheckIsTalbe = false;


            FolderBrowserDialog fbd = new FolderBrowserDialog();

            if (fbd.ShowDialog() == DialogResult.OK)
            {
                string[] files = { "", };

                try
                {
                    files = Directory.GetFiles(fbd.SelectedPath, "*.*", SearchOption.AllDirectories);

                    foreach (string f in files)
                    {
                        // DataSet안에 해당하는 DataTable이 있는지 확인 한다
                        if (ds.Tables.Contains("FileSearch"))
                        {
                            bCheckIsTalbe = true;
                        }

                        DataTable dt = null;

                        if (!bCheckIsTalbe)  // 기존 Table이 없을 경우 신규로 생성
                        {
                            dt = new DataTable("FileSearch");

                            //DataColumn 생성
                            DataColumn colName = new DataColumn("이름", typeof(string));
                            DataColumn colType = new DataColumn("확장자", typeof(string));
                            DataColumn colDate = new DataColumn("수정한 날짜", typeof(string));
                            DataColumn colSize = new DataColumn("크기", typeof(string));

                            //생성된 Column을 DataTable에 Add
                            dt.Columns.Add(colName);
                            dt.Columns.Add(colType);
                            dt.Columns.Add(colDate);
                            dt.Columns.Add(colSize);
                        }
                        else // 기존 Table이 있을 경우 기존 Table을 가져온다
                        {
                            dt = ds.Tables["FileSearch"];
                        }

                        FileInfo info = new FileInfo(files[cnt]);

                        //이름, 확장명, 수정한 날짜, 크기
                        string strFileName = info.Name;
                        int lastIndex = strFileName.LastIndexOf('.');

                        // 이름만 출력될 수 있도록 뒤에 .부터 자른다.
                        string strResult = $"{strFileName.Substring(0, lastIndex)}";  //가공된 이름

                        string strFileType = info.Extension;  // 확장자명
                        string strFileDate = info.LastWriteTime.ToString(); // 수정한 날짜
                        string strFileSize = GetFileSize(info.Length); // 크기


                        if (files.IsFixedSize)
                        {
                            cnt++;
                        }

                        //Row 생성
                        DataRow row = dt.NewRow();
                        row["이름"] = strResult;
                        row["확장자"] = strFileType;
                        row["수정한 날짜"] = strFileDate;
                        row["크기"] = strFileSize;

                        //생성된 Row을 DataTable에 Add
                        if (bCheckIsTalbe)
                        {
                            // DataSet에 해당 DataTalbe이 있을 경우 기존 Table에 Row를 추가한다
                            ds.Tables["FileSearch"].Rows.Add(row);  
                        }
                        else
                        {
                            dt.Rows.Add(row);   // 신규로 작성한 DataTable에 Row를 등록 하고, 
                            ds.Tables.Add(dt);  // 등록한 DataTable을 DataSet에 추가한다
                        }
                    }
                    //DataGridView에 내용출력
                    dataGridView1.DataSource = ds.Tables["FileSearch"];

                    //DataGridView 컬럼 속성 설정
                    dataGridView1.Columns["수정한 날짜"].Width = 140;

                }
                catch (IOException ex)
                {
                    MessageBox.Show(ex.Message);
                }

                cnt = 0;

            }
        }
 
 

보통 DataSet을 활용할때 텍스트파일, Excel 또는 DB를 이용해서

데이터를 저장하고 불러오는 방법을 많이 쓰지만

단순히 해당 폴더에 있는 파일데이터를 불러오는것이 목적이기때문에

따로 텍스트파일이나 excel, DB에는 저장하지 않겠습니다.

모두 메모리상에서만 이루어지는 것이기때문에

프로그램이 종료되면 모두 지워집니다.

 

 

 

 

 

 

 

'Programing > C#' 카테고리의 다른 글

C# LOG파일 생성  (0) 2022.03.12
C# CrossThread Error 해결  (0) 2022.02.21
C# Panel에 간단하게 타원(Rectangle)그리기  (0) 2019.12.17
[DevExpress] SimpleButton 색변경  (0) 2018.10.04
[DevExpress] XtraMessageBox DialogResult Settings  (0) 2018.10.04

1. 150x150 Panel를 만든다.

2. Paint 이벤트를 추가한다.

3. 코드 한줄 추가한다. e.Graphics.FillEllipse(new SolidBrush(Color.Red), new Rectangle(15, 5, 120, 140));

결과

SimpleButton 색상 변경


SimpleButton의 색을 변경하려면  LookAndFeel.StyleFlat, Ultra Flat 또는 Style3D로 설정해야합니다.


this.Exit_btn.LookAndFeel.Style = LookAndFeelStyle.Flat;

this.Exit_btn.LookAndFeel.UseDefaultLookAndFeel = false;

this.Exit_btn.Appearance.BackColor = Color.White;

this.Exit_btn.Appearance.Options.UseBackColor = true;



XtraMessageBox 기본출력


if (DialogResult.Yes == XtraMessageBox.Show("프로그램을 종료하시겠습니까?", "프로그램 종료!", MessageBoxButtons.YesNo, MessageBoxIcon.Stop))

{

        this.close();

}



[ 결과 이미지 ]


기본출력 이미지입니다. 

뭔가 색상과 글씨크기가 맘에 들지 않습니다.

그래서 자신이 원하는 디자인으로 바꿔보겠습니다.


DevExpress.XtraEditors.XtraMessageBox.AllowHtmlText = true; // Html사용

if (DialogResult.Yes == XtraMessageBox.Show("<size=10><color=blue>프로그램을 종료하시겠습니까?</color></size>", 

"<size=10>프로그램 종료!</size>", MessageBoxButtons.YesNo, MessageBoxIcon.Stop))

{

    this.close();

}


[ 결과 이미지 ]


Html을 사용하여 간단히 바꿔보았습니다.





[응용] DialogButton icon add 아이콘 추가


DialogButton에 Yes, No에 각각 아이콘을 추가해보겠습니다.

[1]. Form에 svgImageCollection 도구를 추가합니다.

.


[2]. From DevExpress Gallery를 클릭해서 사용할 아이콘들을 선택, 확인합니다.

 



[3]. Edit Collection에서 선택했던 아이콘을 확인합니다.




[4]. 코드작성

private void Exit_btn_Click(object sender, EventArgs e)

{

    DevExpress.XtraEditors.XtraMessageBox.AllowHtmlText = true;

    XtraMessageBoxArgs args = new XtraMessageBoxArgs();

    args.Caption = "<size=10><color=red>주의!</color></size>";   //제목 텍스트 

    args.Text = "<size=10>프로그램을 종료하시겠습니까?<size=10>";  // 내용 텍스트 

    args.Buttons = new DialogResult[] { DialogResult.OK, DialogResult.Cancel };

    args.Showing += Args_Showing;

    

    if (DialogResult.OK == XtraMessageBox.Show(args))

    {

        Application.Exit();

    }

}



private void Args_Showing(object sender, XtraMessageShowingArgs e)

{

    foreach (var control in e.Form.Controls)

    {

        SimpleButton button = control as SimpleButton;

        if (button != null)

        {

            button.ImageOptions.SvgImageSize = new Size(16, 16); //표시되는 아이콘 크기설정

            button.Font = new System.Drawing.Font(button.Font.FontFamily, 10); //버튼 폰트 크기설정

            //button.Height = 25; 

            switch (button.DialogResult.ToString())

            {

                case ("OK"):

                    button.ImageOptions.SvgImage = svgImageCollection1[0]; //Edit Collection에서 Itme에 첫번째 등록되있는 svg이미지를 불러온다

                    //button.Text = "네";  //버튼이름변경

                    break;

                case ("Cancel"):

                    button.ImageOptions.SvgImage = svgImageCollection1[1];

                    //button.Text = "아니오";

                    break;

                    }

                }

            }

        }


[ 결과 이미지 ]



[1]. DateTimestring으로 변환


DateTime myDateTime = DateTime.Now;


//DateTime을 string으로 변환

string myConvertDateTime = myDateTime.ToString("yyyy/MM/dd hh:mm:ss");

Label1.Text = myConvertDateTime;




[2]. DateTimePickerstring으로 변환


DateTimePicker myDateTime = new DateTimePicker();


//DateTimePicker를 string으로 변환

 Label1.Text = myDateTime .Value.ToString("yyyy/MM/dd hh:mm:ss");


'Programing > C#' 카테고리의 다른 글

[DevExpress] SimpleButton 색변경  (0) 2018.10.04
[DevExpress] XtraMessageBox DialogResult Settings  (0) 2018.10.04
아이디 등록시 특수문자 체크  (0) 2018.09.18
[DevExpress] WinForm WaitIndicator  (0) 2018.09.05
set, get 접근자  (0) 2018.06.29

정규식

- 정해진 패턴을 사용해서 일치하는 데이터 검색을 지원하는 표현식 


정규식을 이용해서 특수문자를 제거 또는 지정한 특수문자를 사용할 수 있습니다.

그리고 Regex클래스를 이용한다. using System.Text.RegularExpressions; 네임스페이스 필요


< 정규 표현식에 사용되는 특수 문자 >

1. '.' (점)

 - 임의의 한 문자를 의미합니다.

ex) f. c -> fac, fbc, frc ...

     . fc -> afc, bfc, rfc ...


2. '*'

 - 바로 앞의 문자가 없거나 하나 이상인 경우

ex) f*c  -> c, fc, fcc, fffc ...

    fps* -> fp, fps, fpss, fpsss ...


3. '+'

 - 바로 앞의 문자가 하나 이상인 경우

ex) f+c -> fc, ffc, fffc ...


4. '?'

 - 바로 앞의 문자가 없거나 하나뿐인 경우

ex) fp?s -> s, fps 두가지 표현이 유일


5. '^'

 - 바로 뒤에 문자열로 시작

ex) ^The... 뒷부분부터 공백까지 검사. -> The girl is, Theather

^.e -> he, me, request, settle ...


6. '$'

 - 바로 앞의 문자열로 종료

ex) a?bc$ -> eeabe, seebc, bc ...

+.e$ -> onthetoe, bctae, appetittle ... 


7. '[ ]'

 - [ ] 안에 있는 문자 중 하나( 범위의 경우 '-'로 지정합니다. )

ex) [ab]cd -> acd, bcd ...

     [ a-z ] -> 알파벳 소문자

     [a-zA-Z] -> 알파벳 소문자, 대문자

     [0-9] -> 숫자

    ^[a-zA-Z] 영문자로 시작

    ^[가-힣] 한글로 시작

     [^a-zA-Z0-9가-힣] 알파벳, 숫자, 힣 사이에 문자가 아닌게 있는지 확인


[Regex 클래스 적용]



아이디 등록시 특수문자가 불가능해야되기 때문에 체크를 해줘야 한다.



특수문자가 있는지 확인하기 위해서 string 정규식을 이용하여 특수문자를 뺀 문자를 받는다.

string idChecker = Regex.Replace(USER_ID.Text, @"[ ^0-9a-zA-Z가-힣 ]{1,10}", "", RegexOptions.Singleline);


그리고 원래의 string과 비교 후 다르면 에러메시지창을 띄운다.

if( USER_ID.Text.Equals(idChecker) == false )

{

USER_ID.Text.Remove( 0, USER_ID.Text.Length );

USER_ID.Text = "";

DXMessageBox.Show("특수문자, 공백은 허용되지 않습니다..");

}



아이디에 지정한 특수문자(&)를 넣고 싶은 경우에는 \&를 추가하면 된다.

string idChecker = Regex.Replace(USER_ID.Text, @"[ ^0-9a-zA-Z가-힣\& ]{1,10}", ""RegexOptions.Singleline);


'Programing > C#' 카테고리의 다른 글

[DevExpress] XtraMessageBox DialogResult Settings  (0) 2018.10.04
Datetime, DatetimePicker을 string으로 변환  (0) 2018.10.01
[DevExpress] WinForm WaitIndicator  (0) 2018.09.05
set, get 접근자  (0) 2018.06.29
할당문과 변수초기화  (0) 2018.06.29

WinForm WaitIndicator 추가방법


추가할 프로젝트 우클릭 -> Add DevExpress Item -> New Item -> Progress Indicator 추가



[ MouseClick_Event ] 부분에 추가


UserLookAndFeel.Default.SetSkinStyle("Office 2013 Dark Gray");// 사용할 디자인(여러가지 스타일이 있음 속성확인후 적용)

SplashScreenManager.ShowForm(null, typeof(Frm_WaitForm), true, true, false);   // 스크린출력    

SplashScreenManager.Default.SetWaitFormCaption("잠시기다려주세요...");   // 출력되는 메시지 입력

SplashScreenManager.CloseForm();  // 출력해제



기타 배경색, 폰트크기, 폰트컬러등등 속성에서 변경가능 

'Programing > C#' 카테고리의 다른 글

Datetime, DatetimePicker을 string으로 변환  (0) 2018.10.01
아이디 등록시 특수문자 체크  (0) 2018.09.18
set, get 접근자  (0) 2018.06.29
할당문과 변수초기화  (0) 2018.06.29
상수(Constant)  (0) 2018.06.28

+ Recent posts