CheckForIllegalCrossThreadCalls = false;

 

어디까지나 임시방편 


결국에는 invoke 또는  BackgroundWorker를 사용해서 수정해야함.

오픈소스 사용함

 

URL: https://github.com/Enichan/Ini

 

GitHub - Enichan/Ini: Ini file reader/writer for C# / .NET written in pure .NET in a single source file

Ini file reader/writer for C# / .NET written in pure .NET in a single source file - GitHub - Enichan/Ini: Ini file reader/writer for C# / .NET written in pure .NET in a single source file

github.com

 

 

Ini.cs
0.03MB

 

Kernel32를 사용하지 않고 cs파일 하나만 추가해서 매우 간단하고 직관적으로 코딩할수 있다.

 

 

            // ini 쓰기
            IniFile ini = new IniFile();
            ini["Setting"]["USE_FLAG"] = "true";
            ini["Setting"]["Delay_Time"] = "10";
            ini["INPUT_DATA"]["TEXT1"] = "DATA1";
            ini.Save("C:\\Setting.ini");
 
            // ini 읽기
            ini.Load("C:\\Setting.ini");
            string useflag = ini["Setting"]["USE_FLAG"].ToString();
            string delay_time = ini["Setting"]["Delay_Time"].ToString();
            string textdata1 = ini["INPUT_DATA"]["TEXT1"].ToString();

 

진짜 많이 검색해보고 나름대로 가장 심플하면서 확실한 방법을 찾은거같아서 글을 작성합니다.

 

그냥 Excel.EXE 프로세스를 죽이게 되면 다른 실행되있는 엑셀파일도 전부 날아가기때문에

 

엑셀의 PID(Process ID)를 획득 후 해당 ID에 대해서만 Kill하게 됩니다.

 

예제)

    class Program
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        static void Main(string[] args)
        {
            Microsoft.Office.Interop.Excel.Application excel = null;
            Workbook workbook = null;
            Worksheet worksheet = null;
            uint processId = 0;

            excel = new Microsoft.Office.Interop.Excel.Application();
            // 엑셀 내용 Start
                      º
                      º
                      º  
                      º
                      º
            // 엑셀 내용 End
            
            GetWindowThreadProcessId(new IntPtr(excel.Hwnd), out processId); //PID 획득
            workbook .Save();       
            workbook.Close(Type.Missing, Type.Missing, Type.Missing);     
            excel.Quit();

            if (processId != 0)
            {
                System.Diagnostics.Process excelProcess = System.Diagnostics.Process.GetProcessById((int)processId);
                excelProcess.CloseMainWindow();
                excelProcess.Refresh();
                excelProcess.Kill();
            }
        }
    }

 

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

C# 디버깅시 Cross Thread 임시 해결방법  (0) 2022.05.09
C# ini 파일 읽기 쓰기  (0) 2022.04.22
C# Excel 프로세스 해제  (0) 2022.03.12
C# LOG파일 생성  (0) 2022.03.12
C# CrossThread Error 해결  (0) 2022.02.21

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:")

Tibero에 대해 간단히 설명하자면 오라클과 매우 비슷한 국산 DB인데 TmaxSoft에서 개발했습니다.

 

버전은 티베로6버전으로 진행했고 구글에 검색해도 자료가 많이 없어서 불편했습니다.

 

그래서 저처럼 시간낭비 하지마시라구 자세하게 내용정리합니다.

 

LOCAL DB FULL INSTALL이 아닌 다른 서버에 접속할수 있도록

 

Tibero6 드라이버 설치와 OLEDB 연동을 통해 DB에 접속을 해봅니다.

 

1. ODBC에 연결하기 위해서 https://technet.tmaxsoft.com 에 접속해서 다운로드 합니다.

 - 파일을 다운로드 하기위해서는 회원가입 후 로그인해야합니다.

 

드라이버 설치와 lib파일만 필요하기 때문에 하단에 256MB 파일을 다운로드합니다.

 

tbodbc_driver_installer_6_32.exe
0.12MB
tbodbc_driver_installer_6_64.exe
0.18MB

 

lib_32.zip
3.52MB
lib_64.zip
3.99MB

 

 

 

 

2. 해당 이미지와 같이 C드라이브에 폴더를 생성 후 파일을 붙여넣고 환경변수를 설정합니다.

 

 

bin 폴더안에 64bit, 32bit 해당 라이브러리 파일을 붙여넣습니다.

 

환경변수를 설정합니다.

 

 

 

 

3. 드라이버 설치를 합니다.

cmd창을 실행시킨 후 드라이버가 있는 해당 폴더로 이동한뒤 위 이미지처럼 명령어를 입력합니다.

Success to INSTALL Tibero 6 ODBC Driver 메세지가 출력되면 성공적으로 설치가 완료됐습니다.

 

 

dll을 레지스트리에 등록합니다.

마찬가지로 해당 이미지와 같이 dll도 등록해줍니다.

 

 

 

 

ODBC 관리자에 가면 정상적으로 활성화 되있는것을 확인할 수 있습니다.

 

 

 

시스템 DNS에서 추가합니다

 

 

접속하려는 서버IP와 PORT DB NAME, ID와 PWD를 입력 후 Test를 클릭해서 테스트를 해봅니다.

정상적으로 연결된 경우 Connection Success라는 메시지가 출력됩니다.

 

 

 

4. 설치가 전부 완료됐습니다. 이제 OLEDB 연동을 시작하겠습니다.

 

 

프로젝트 생성 후 해당 dll을 추가해줍니다.

 

Using System.Data.OleDb;


string sql = "Provider=tbprov.Tbprov.6; Data Source =192.168.0.1, 7000, DBTest; User ID = admin; Password=admin99;"
               + "Persist Security Info = True";              //      서버IP, PORT, DB Name;    ID;          PWD;  작성해주면 됩니다. 

            conn = new OleDbConnection(sql);
            conn.Open();

            OleDbCommand cmd = new OleDbCommand("select * from 테이블");
            cmd.Connection = conn; // Connection 초기화 하지 않으면 속성이 초기화되지 않았다는 에러메세지가 뜬다.
            OleDbDataReader read = cmd.ExecuteReader();
            while (read.Read())
            {
                string txtData = read.GetValue(1).ToString();
            }

            read.Close();
            conn.Close();

이상으로 티베로 드라이버 설치와 OLEDB 연동을 간단하게 알아보았습니다.

'Programing > Oracle' 카테고리의 다른 글

같은 테이블 다중행 삽입(MULTIPLE INSERT)  (0) 2023.01.20
상위 n개 데이터 출력  (0) 2022.02.21

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

 

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;
                }));
            }
        }

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

기본 

- 10개 상위 데이터 출력

SELECT * FROM 테이블 WHERE ROWNUM <= 10

 

응용

- 정렬된 값을 10개 상위 데이터 출력

SELECT * FROM ( SELECT * FROM 테이블 ORDER BY 값 DESC ) WHERE ROWNUM <=10

'Programing > Oracle' 카테고리의 다른 글

같은 테이블 다중행 삽입(MULTIPLE INSERT)  (0) 2023.01.20
Tibero 드라이버 설치와 OleDB연동  (0) 2022.02.21

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));

결과

+ Recent posts