//11.txt
//{"param":{"loginid":"admin","pwd":"admin123"},"proto":"r","sender":"/cli/admin/10.1.181.79/25216","id":"login_client.0000919860.001","ts":"1713428639","method":"login_client"}

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

class Program
{
    public static void Main(string[] args)
    {
        if (args.Length == 1)
        {
            CHKNM nmm = new CHKNM();
            nmm.RUN(args[0]);
        }
        else
        {
            CHKNM nmm = new CHKNM();
            nmm.RUN();
        }
    }
}
class CHKNM
{
    public void RUN(string fileText)
    {
        string lines = File.ReadAllText(fileText);

        Console.WriteLine(lines);

        byte[] bytes = Encoding.UTF8.GetBytes(lines);
        PrintByteArray(bytes);
    }
    public void RUN()
    {
        byte[] buffer = new byte[] { 123, 34, 112, 97, 114, 97, 109, 34, 58, 123, 34, 108, 111, 103, 105, 110, 105, 100, 34, 58, 34, 97, 100, 109, 105, 110, 34, 44, 34, 112, 119, 100, 34, 58, 34, 97, 100, 109, 105, 110, 49, 50, 51, 34, 125, 44, 34, 112, 114, 111, 116, 111, 34, 58, 34, 114, 34, 44, 34, 115, 101, 110, 100, 101, 114, 34, 58, 34, 47, 99, 108, 105, 47, 97, 100, 109, 105, 110, 47, 49, 48, 46, 49, 46, 49, 56, 49, 46, 55, 57, 47, 50, 53, 50, 49, 54, 34, 44, 34, 105, 100, 34, 58, 34, 108, 111, 103, 105, 110, 95, 99, 108, 105, 101, 110, 116, 46, 48, 48, 48, 48, 57, 49, 57, 56, 54, 48, 46, 48, 48, 49, 34, 44, 34, 116, 115, 34, 58, 34, 49, 55, 49, 51, 52, 50, 56, 54, 51, 57, 34, 44, 34, 109, 101, 116, 104, 111, 100, 34, 58, 34, 108, 111, 103, 105, 110, 95, 99, 108, 105, 101, 110, 116, 34, 125, 13, 10, };
        string strText = Encoding.Default.GetString(buffer);

        Console.WriteLine(strText);
    }
    public void PrintByteArray(byte[] bytes)
    {
        var sb = new StringBuilder("new byte[] { ");
        foreach (var b in bytes)
        {
            sb.Append(b + ", ");
        }
        sb.Append("}");
        Console.WriteLine(sb.ToString());
    }
}





windows_send_basic.exe 127.0.0.1 21111 "E:\exture_plus_raw_internet_log_20230418\home\release\Paxfeed_x64\backup\TickerplantRaw_EXTURE_PLUS_INTERNET_REAL_STANDBY\20230418_13_internet_Kse_32114.log"

-rw-r--r-- 1 B210145_BK 197121       2944 Apr 18  2023 20230418_20_internet_Kse_32113.log
-rw-r--r-- 1 B210145_BK 197121       2944 Apr 18  2023 20230418_20_internet_Kse_32112.log
-rw-r--r-- 1 B210145_BK 197121       2944 Apr 18  2023 20230418_20_internet_Kosdaq_33112.log
-rw-r--r-- 1 B210145_BK 197121    3013444 Apr 18  2023 20230418_20_internet_Kse_32115.log
-rw-r--r-- 1 B210145_BK 197121       3264 Apr 18  2023 20230418_20_internet_FutureIndex_35115.log
-rw-r--r-- 1 B210145_BK 197121       3264 Apr 18  2023 20230418_20_internet_OptionIndex_36112.log
-rw-r--r-- 1 B210145_BK 197121       3264 Apr 18  2023 20230418_20_internet_OptionIndex_36111.log
-rw-r--r-- 1 B210145_BK 197121       2944 Apr 18  2023 20230418_20_internet_Kse_45111.log
-rw-r--r-- 1 B210145_BK 197121       3264 Apr 18  2023 20230418_20_internet_FutureIndex_35114.log
-rw-r--r-- 1 B210145_BK 197121       2944 Apr 18  2023 20230418_20_internet_Kse_32114.log
-rw-r--r-- 1 B210145_BK 197121       5520 Apr 18  2023 20230418_20_internet_Elw_34913.log
-rw-r--r-- 1 B210145_BK 197121       5460 Apr 18  2023 20230418_20_internet_Kse_40116.log
-rw-r--r-- 1 B210145_BK 197121       5460 Apr 18  2023 20230418_20_internet_Kse_40112.log
-rw-r--r-- 1 B210145_BK 197121       5460 Apr 18  2023 20230418_20_internet_Kse_40111.log
-rw-r--r-- 1 B210145_BK 197121       5520 Apr 18  2023 20230418_20_internet_Elw_34912.log
-rw-r--r-- 1 B210145_BK 197121       5612 Apr 18  2023 20230418_20_internet_Elw_34914.log

windows_send_basic.c
0.00MB
windows_recv_basic.c
0.00MB
linux_recv_basic.c
0.00MB

플랫버퍼에서 데이터를 읽고 쓰는 방법은 다음과 같습니다.

1.데이터 구조 정의: 먼저 플랫버퍼에서 사용할 데이터 구조를 정의해야 합니다. 이를 위해 플랫버퍼에서 제공하는 FlatBufferBuilder 클래스를 사용합니다. FlatBufferBuilder 클래스는 데이터 구조를 생성하고, 데이터를 추가하며, 최종적으로 직렬화된 데이터를 생성하는 데 사용됩니다.

2.데이터 추가: FlatBufferBuilder 클래스를 사용하여 데이터 구조에 데이터를 추가합니다. 데이터를 추가할 때는 FlatBufferBuilder 클래스의 메소드를 사용합니다. 예를 들어, int 타입의 데이터를 추가하려면 FlatBufferBuilder.addInt 메소드를 사용합니다.

3.데이터 직렬화: 데이터 추가가 완료되면, FlatBufferBuilder 클래스의 Finish 메소드를 사용하여 데이터를 직렬화합니다. Finish 메소드는 직렬화된 데이터를 반환합니다.

4.데이터 읽기: 직렬화된 데이터를 읽으려면, FlatBufferBuilder 클래스에서 제공하는 GetRootAs 메소드를 사용합니다. 이 메소드는 직렬화된 데이터에서 원하는 데이터 구조를 추출하는 데 사용됩니다. 추출된 데이터 구조는 해당 언어에서 제공하는 방식으로 사용할 수 있습니다.

5.데이터 수정: 추출된 데이터 구조를 수정하려면, 해당 언어에서 제공하는 방식으로 데이터를 수정합니다. 수정된 데이터를 다시 직렬화하려면, FlatBufferBuilder 클래스를 사용하여 데이터를 추가하고, Finish 메소드를 사용하여 데이터를 직렬화합니다.

다음은 C++에서 플랫버퍼를 사용하여 데이터를 읽고 쓰는 예제입니다.

#include "flatbuffers/flatbuffers.h"

struct Person {
    int id;
    std::string name;
    int age;
};

int main() {
    // 데이터 구조 정의
    FlatBufferBuilder builder;

    // 데이터 추가
    auto nameOffset = builder.CreateString("John");
    auto person = CreatePerson(builder, 1, nameOffset, 30);

    // 데이터 직렬화
    FinishPersonBuffer(builder, person);

    // 데이터 읽기
    auto buffer = builder.GetBufferPointer();
    auto person_ = GetPerson(buffer);

    // 데이터 출력
    std::cout << "ID: " << person_->id() << std::endl;
    std::cout << "Name: " << person_->name()->c_str() << std::endl;
    std::cout << "Age: " << person_->age() << std::endl;

    return 0;
}

SBE (Simple Binary Encoding)는 성능에 민감한 애플리케이션을 위한 경량의 고성능 바이너리 데이터 인코딩 및 직렬화 형식입니다. SBE는 금융 서비스, IoT, 산업 자동화, 네트워크 모니터링 등 다양한 산업 분야에서 사용됩니다.

다음은 SBE의 주요 특징입니다:

1.고성능: SBE는 경량의 바이너리 형식을 사용하여 데이터를 인코딩하고 직렬화하므로, 데이터 전송 및 처리 속도가 빠릅니다.

2.유연성: SBE는 사용자가 데이터 구조를 정의하고, 필드의 길이, 데이터 타입, 값의 범위 등을 지정할 수 있습니다. 이를 통해 사용자는 자신의 요구사항에 맞게 데이터를 인코딩할 수 있습니다.

3.다양한 언어 지원: SBE는 C++, Java, .NET, Python, JavaScript 등 다양한 언어를 지원합니다. 이를 통해 여러 언어로 작성된 애플리케이션 간에 데이터를 쉽게 교환할 수 있습니다.

4.안전성: SBE는 데이터 무결성을 보장하기 위해 체크섬을 사용합니다. 또한, 데이터가 손상되는 것을 방지하기 위해 오류 검사를 수행합니다.

5.확장성: SBE는 대규모 데이터 처리를 위한 확장성이 높습니다. 이를 통해 대량의 데이터를 빠르고 안정적으로 처리할 수 있습니다.

6.표준화: SBE는 금융 서비스 산업에서 널리 사용되는 FIX (Financial Information eXchange) 프로토콜을 기반으로 개발되었습니다. 이를 통해 SBE는 금융 서비스 분야에서 표준화된 데이터 인코딩 형식으로 자리 잡았습니다.

SBE는 금융 서비스 분야에서 널리 사용되고 있으며, 다른 산업 분야에서도 점차 도입되고 있습니다. SBE를 사용하면 데이터 전송 및 처리 속도를 향상시키고, 데이터 무결성을 보장하며, 다양한 언어로 작성된 애플리케이션 간에 데이터를 쉽게 교환할 수 있습니다.

플랫버퍼(FlatBuffers)는 C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust 및 Swift를 위한 효율적인 크로스 플랫폼 직렬화 라이브러리입니다. 원래 게임 개발 및 기타 성능에 민감한 애플리케이션을 위해 구글에서 만들었습니다.

플랫버퍼는 데이터를 효율적으로 저장하고 전송하기 위해 설계되었습니다. 이는 메모리 사용량과 직렬화 및 역직렬화 시간을 최소화함으로써 이루어집니다. 또한 다양한 언어를 지원하므로 여러 언어로 작성된 애플리케이션 간에 데이터를 쉽게 교환할 수 있습니다.

플랫버퍼는 다음과 같은 특징을 가지고 있습니다:

1.효율성: 플랫버퍼는 데이터를 압축하여 저장하므로 메모리 사용량을 최소화합니다. 또한 직렬화 및 역직렬화 시간이 매우 빠릅니다.

2.다양한 언어 지원: 플랫버퍼는 다양한 언어를 지원하므로 여러 언어로 작성된 애플리케이션 간에 데이터를 쉽게 교환할 수 있습니다.

3.유연성: 플랫버퍼는 사용자가 데이터 구조를 정의하고 직렬화할 수 있게 해줍니다. 또한 사용자가 직렬화된 데이터를 수정하고 역직렬화할 수 있습니다.

4.빠른 속도: 플랫버퍼는 데이터를 빠르게 읽고 쓸 수 있으므로 게임 개발이나 실시간 데이터 처리와 같은 성능에 민감한 애플리케이션에 적합합니다.

5.안전성: 플랫버퍼는 데이터 무결성을 보장하기 위해 체크섬을 사용합니다. 또한 데이터가 손상되는 것을 방지하기 위해 오류 검사를 수행합니다.

6.오픈 소스: 플랫버퍼는 오픈 소스 라이브러리이므로 누구나 자유롭게 사용하고 수정할 수 있습니다.

플랫버퍼는 게임 개발, 머신 러닝, 빅 데이터 처리 등 다양한 분야에서 사용됩니다. 또한 웹 개발에서도 사용되며, JSON과 같은 다른 직렬화 형식보다 더 효율적이고 빠릅니다.

json 데이타를 c# 구조체 모델링 코드화 해주는 사이트
json 데이타를 c# 구조체 모델링 코드화 해주는 사이트
json 데이타를 c# 구조체 모델링 코드화 해주는 사이트

https://json2csharp.com/

json 데이타를 c# 구조체 모델링 코드화 해주는 사이트
json 데이타를 c# 구조체 모델링 코드화 해주는 사이트
json 데이타를 c# 구조체 모델링 코드화 해주는 사이트

https://json2csharp.com/

1. 특정 폴더 일괄 지우기(특정 폴더)

find . -name "test" -type d -exec rm -rf {} \;
or
find . -name "test*" -type d | xargs rm -rf

하위까지(APM),ㅡㅡㅡㅡㅡ
find ./ -name "obj" -type d | xargs rm -rf
find ./ -name "obj" -type d | xargs rm -rf
find ./ -name "obj" -type d | xargs rm -rf

2. 특정 파일 일괄 지우기

find . -name "test" -type f -exec rm -rf {} \;
or
find . -name "*test*" -type f | xargs rm -rf


case1)
Application.Exit();

case2)
System.Diagnostics.Process.GetCurrentProcess().Kill();

using System;
using System.Collections.Generic;
using System.Linq;
using Systehttp://m.Text.Json;
using StackExchange.Redis;

class Program
{
    public static void Main(string[] args)
    {
        REDISCHK nmm = new REDISCHK();
        nmm.RUN();
    }
}
class REDISCHK
{
    public void RUN()
    {
        RedisStore redis = new RedisStore("localhost:6379");

        /*---------------------------------------------------------------------------
        // key, value로 저장
        redis.SetValue("test1", "ans-test1");

        // key로 value를 찾는다.
        //Console.WriteLine(redis.GetValue("test1"));
       ---------------------------------------------------------------------------*/

       /*
        FILE을 읽어서, KEY=ifReceiver.sender
        VALUE=formatText
       */
    }
}

 

 

# DispatcherTimer  활용사례

using System;
using System.Windows.Threading;
using Systehttp://m.Windows.Forms;
using System.Timers;
using System.IO;

namespace APM
{
    public partial class APMMain : Form
    {
        private DispatcherTimer displayTimer1 = new DispatcherTimer(); //유가
        private DispatcherTimer displayTimer2 = new DispatcherTimer(); //코스닥
        private DispatcherTimer displayTimer3 = new DispatcherTimer(); //파생
        private DispatcherTimer displayTimer4 = new DispatcherTimer(); //채권

        private int sec1, sec2, sec3, sec4;


        public APMMain()
        {
            InitializeComponent();

            InitControl();
        }
        void InitControl()
        {
            

            displayTimer1.Interval = TimeSpan.FromSeconds(interval);
            displayTimer1.Tick += new EventHandler(displayTimer_Tick);
            sec1 = 0;
            displayTimer2.Interval = TimeSpan.FromSeconds(interval);
            displayTimer2.Tick += new EventHandler(displayTimer_Tick);
            sec2 = 0;
            displayTimer3.Interval = TimeSpan.FromSeconds(interval);
            displayTimer3.Tick += new EventHandler(displayTimer_Tick);
            sec3 = 0;
            displayTimer4.Interval = TimeSpan.FromSeconds(interval);
            displayTimer4.Tick += new EventHandler(displayTimer_Tick);
            sec4 = 0;

            displayTimer1.Start();
            displayTimer2.Start();
            displayTimer3.Start();
            displayTimer4.Start();

            
        }

        void displayTimer_Tick(object sender, EventArgs e)
        {
            if ((sender as DispatcherTimer).Equals(displayTimer1))
            {
                TimeSpan t = TimeSpan.FromSeconds(sec1++);
                timer1.Text = string.Format("{0:D2}:{1:D2}", t.Minutes, t.Seconds);
            }

            else if ((sender as DispatcherTimer).Equals(displayTimer2))
            {
                TimeSpan t = TimeSpan.FromSeconds(sec2++);
                timer2.Text = string.Format("{0:D2}:{1:D2}", t.Minutes, t.Seconds);
            }

            else if ((sender as DispatcherTimer).Equals(displayTimer3))
            {
                TimeSpan t = TimeSpan.FromSeconds(sec3++);
                timer3.Text = string.Format("{0:D2}:{1:D2}", t.Minutes, t.Seconds);
            }

            else if ((sender as DispatcherTimer).Equals(displayTimer4))
            {
                TimeSpan t = TimeSpan.FromSeconds(sec4++);
                timer4.Text = string.Format("{0:D2}:{1:D2}", t.Minutes, t.Seconds);
            }
        }

        #region WndProc
        protected override void WndProc(ref Message m)
        {

            switch (m.Msg)
            {
                default:
                    break;
            }
            base.WndProc(ref m);
        }
        #endregion   

        public void SetRegin()
        {
            //
        }
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }
    }
}

(1)라이선스 에러 발생시 대처 방법 안내/(2)마이그레이션 방법
(1)라이선스 에러 발생시 대처 방법 안내/(2)마이그레이션 방법
(1)라이선스 에러 발생시 대처 방법 안내/(2)마이그레이션 방법

마이그레이션
라이선스 에러 발생시 대처 방법 안내 - 마이그레이션 방법

ComponentOne(컴포넌트원)을 사용하여 개발한 솔루션 빌드 또는 실행시에 발생하는 라이선스의 에러에 대해서 알아보고, 이를 대처 하는 방법을 설명합니다. 

빌드 또는 실행 시, 라이선스 에러가 발생하는 주요 원인은 아래와 같습니다. 

구버전에서 신버전으로 업그레이드를 하시는 경우
다른 PC에서 다른 C1버전으로 개발한 소스를 가져와서 사용하시는 경우
체험판 상태에서 프로젝트를 개발하다가 정식 라이선스를 사용하시는 경우

위와 같은 경우, 
이전 프로젝트에서 사용했던 Licenses.licx 또는 DLL들의 버전 정보와 현재 설치된 ComponentOne 제품의 버전 정보가 일치하지 않아 라이선스 에러 또는 빌드 에러가 발생할 수 있습니다.
이 경우, 라이선스 마이그레이션 과정으로 통해 프로젝트에서 참조 중인 DLL들과 Licenses.licx 정보를 업데이트하면 됩니다. 
아래의 과정을 따라해 주시기 바랍니다. 

라이선스 활성화 확인

1. 먼저 프로젝트를 빌드하기 위해서는 정상적으로 라이선스가 설치(액티베이션) 되어 있어야 합니다. 라이선스가 액티베이션(활성화)이 되어 있는지 확인하기 위해서는 아래와 같은 과정을 따라하시면 됩니다.

[2020 V2 이상 버전]
구매 시에 메일의 링크를 통해서 받으신 설치 프로그램인 ComponentOneControlPanelKR.exe를 실행하셔서 아래와 같이 라이선스 - 비활성화 탭을 클릭합니다.
라이선스 키 부분의 콤보박스를 클릭하면 현재 설치되어 있는 라이선스를 보실 수 있습니다. 여기에서 라이선스가 보여진다면 액티베이션이 되어 있는 것입니다.

또는 아래와 같은 GrapeCity License Manager를 통해서도 확인이 가능합니다.

- 프로그램 위치: C:\ProgramData\GrapeCity\gclm\gclm.exe 
(윈도우 시작 버튼 클릭 후 License Manager로 검색하여 실행하실 수도 있습니다.) 

프로그램에서 Product License Activated 항목이 보여 진다면 해당 제품 (아래 예제의 경우에는 ComponentOne Studio Enterprise 제품)이 정상적으로 활성화가 된 것입니다.

[2020 V1 이하 버전]

C1LicenseActivation 프로그램을 사용하시면 됩니다.

해당 프로그램은 아래의 위치에 존재합니다.

C:\Program Files (x86)\Common Files\ComponentOne Shared\C1LicenseActivation.exe 
이 프로그램에서 Serial Number부분의 (물음표) 버튼을 클릭하셨을 때 라이선스가 보여진다면 정상적으로 액티베이션(활성화)이 되어 있다고 생각하시면 됩니다.

이렇게 확인했을 때 액티베이션이 되어 있지 않다면 아래의 글을 참고하셔서 라이선스 
액티베이션을 해주시기 바랍니다.

2020 V2 이상 버전
(2020 V2 이상) 온라인 라이선스 활성화 및 비활성화
(2020 V2 이상) 오프라인 라이선스 인증 및 해제

2020 V1 이하 버전  2020년 10월 이후 구매자
(2020V2 이상) 하위 버전 라이선스 활성화/비활성화 방법 

2020 V1 이하 버전  2020년 9월 이전 구매자
ComponentOne 온라인 라이선스 활성화 및 비활성화

프로젝트 마이그레이션 방법 /프로젝트 마이그레이션 방법 /프로젝트 마이그레이션 방법 /프로젝트 마이그레이션 방법 /프로젝트 마이그레이션 방법 

[방법1: 프로젝트 다시 빌드]

이제 라이선스가 액티베이션(활성화) 되었다면 VisualStudio 빌드 메뉴에서 솔루션 정리 후, 솔루션 다시 빌드한 다음 프로그램을 실행해 보시기 바랍니다.
이것만으로 문제가 해결되는 경우가 있습니다.

[방법2: DLL 및 License.licx 삭제 및 재생성 ]

위 방법을 실행하여도 동일한 문제가 발생한다면, 반드시 프로젝트를 백업하시고 아래의 방법을 따라 마이그레이션을 진행하여 주시기 바랍니다.
솔루션 탐색기의 Properties 하위에 있는 licenses.licx파일과 참조 하위에 있는 C1으로 시작하는 이름을 따로 적어둔 후 모든 dll을 삭제합니다.

실제 프로젝트가 존재하는 경로의 필요 없는 Bin폴더나 Debug 폴더를 모두 삭제합니다.
(만약 Visual Studio가 실행 중이라 해당 폴더가 지워지지 않는다면, Visual Studio를 종료한 다음 삭제합니다.)

솔루션 탐색기의 해당 동일 프로젝트에서 마우스 우클릭 후 빈 Windows Form을 하나 추가합니다.

새로 생성한 빈 폼에 도구 상자로부터 현재 사용중인 C1의 컨트롤을 드래그하여 올려놓습니다.
C1.Win.C1Chart.Toolbar.4.5.2 등의 일부 dll은 도구 상자의 C1 컨트롤을 끌어와 추가하시더라도 자동으로 추가되지 않을 수 있습니다.

이 경우, 참조를 직접 추가하시는 방법을 안내드립니다.참조를 마우스 우클릭하여 참조 추가를 선택합니다.
솔루션 빌드 시, 오류가 발생하는 네임스페이스를 확인하여 [어셈블리 - 확장] 탭에서 찾아 직접 추가합니다.
추가했던 빈 Windows Form을 삭제합니다.

솔루션 내 C1 컨트롤을 사용 중인 모든 프로젝트에 대해 위의 1~5 단계를 반복합니다.
전체 솔루션을 Rebuild 한 후, 프로그램을 실행합니다.
이제 프로젝트 마이그레이션 과정이 완료되었습니다. 




$ find ./ -name licenses.licx | xargs grep Version
./APM/APM/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/APM/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/APMCommManager/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/AMS/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/AMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/AMS/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/CFG/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/CFG/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/DBM/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/DBM/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/DST/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/DST/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/DST/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/INQ/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/INQ/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/MWM/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/MWM/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/MWM/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/PMA/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/PMA/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/PMS/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/PMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/PMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/POP/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/POP/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/RPT/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/RPT/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/RPT/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/RTP/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/RTP/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/SEC/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/SEC/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/SEC/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/SMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/SMS/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/SMS/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TAT/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TAT/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TMS/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20113.21313, Culture=neutral, PublicKeyToken=a22e16972c085838
./APM/Screen/TPS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TPS/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TRA/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TRA/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.1.20113.214, Culture=neutral, PublicKeyToken=79882d576c6336da
./APM/Screen/TRA/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.6.20113.647, Culture=neutral, PublicKeyToken=79882d576c6336da

xterm@DESKTOP-VVAIF4D MINGW64 /d/takeover/exture_apm_30_00
$



After Version Up) After Version Up) After Version Up) After Version Up) After Version Up) After Version Up) After Version Up)



xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/versionup_ver_20_00/APM
$ find ./ -name licenses.licx | xargs grep Version
./APM/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./APMCommManager/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/AMS/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=a22e16972c085838
./Screen/AMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/CFG/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/DBM/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/DST/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/DST/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=a22e16972c085838
./Screen/INQ/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/INQ/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/MWM/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/MWM/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=a22e16972c085838
./Screen/PMA/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/PMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/POP/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/RPT/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/RPT/Properties/licenses.licx:C1.C1Excel.C1XLBook, C1.C1Excel.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/RPT/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=a22e16972c085838
./Screen/RTP/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/SEC/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=a22e16972c085838
./Screen/SEC/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/SMS/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=a22e16972c085838
./Screen/SMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/TAT/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/TMS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/TMS/Properties/licenses.licx:C1.Win.C1Chart.C1Chart, C1.Win.C1Chart.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=a22e16972c085838
./Screen/TPS/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da
./Screen/TRA/Properties/licenses.licx:C1.Win.C1FlexGrid.C1FlexGrid, C1.Win.C1FlexGrid.4, Version=4.0.20183.338, Culture=neutral, PublicKeyToken=79882d576c6336da

xterm@DESKTOP-VVAIF4D MINGW64 ~/Downloads/tmp/versionup_ver_20_00/APM



1.
Component ONE 최신버젼, 도구모음 등록안되는 형상(?)


2.
license.licx 증명서가 삭제되었을때에, 다시 발급받아야 하는가,ㅡ,ㅡ(?)


3.
참조) 라이선스 에러 발생시 대처 방법 안내 - 마이그레이션 방법

license.licx 를 여러개의 프로젝트에서 사용할때에, 즉 여러개의 license.licx가 존재할경우에,

삭제된 프로젝트에 다른 프로젝트의 license.licx를 가져와서 복사 & 붙여넣기해서 재사용이 가능한가,ㅡ,ㅡ(?)


4. 프로젝트의 참조에 사용중인 DLL버젼과 도구모음에 등록되어진 DLL버젼이 틀린경우에 어떤 현상이 나타나는가(?)

단순 편집만 안되는지, 실행하는데는 문제는 없는가,ㅡ,ㅡ(?) 일단 편집은 안되는걸로 확인이 됩니다.

https://dev.mescius.co.kr/bbs/board.php?bo_table=component_faq&wr_id=25&page=1











/*
KEYPOINT) DateTime now = DateTime.ParseExact(MANUAL_DT, "yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture);
*/


using System;
using System.Timers;
using System.IO;


class Program
{
    public static void Main()
    {
        CHKNMNM nmm = new CHKNMNM();
        nmm.CALCCHK();
        nmm.REALCHK();
        nmm.DISPCHK();
    }
}

class CHKNMNM
{
    string[] HOLIDAY = new string[]
    {
        "2024-01-01",
        "2024-02-09",
        "2024-02-12",
        "2024-03-01",
        "2024-04-10",
        "2024-05-01",
        "2024-05-06",
        "2024-05-15",
        "2024-06-06",
        "2024-08-15",
        "2024-09-16",
        "2024-09-17",
        "2024-09-18",
        "2024-10-03",
        "2024-10-09",
        "2024-12-25",
    };
    string[] HOLIDAYNM = new string[]
    {
        "2024-01-01(신정)",
        "2024-02-09(구정)",
        "2024-02-12(구정)",
        "2024-03-01(삼일절)",
        "2024-04-10(선거일)",
        "2024-05-01(노동절)",
        "2024-05-06(어린이날대체)",
        "2024-05-15(부처님오신날)",
        "2024-06-06(현충일)",
        "2024-08-15(광복절)",
        "2024-09-16(추석)",
        "2024-09-17(추석)",
        "2024-09-18(추석)",
        "2024-10-03(개천절)",
        "2024-10-09(한글날)",
        "2024-12-25(크리스마스)",
    };
    string[] YOIL = new string[]
    {
    "MONDAY",
    "TUESDAY",
    "WEDNESDAY",
    "THURSDAY",
    "FRIDAY",
    "SATURDAY",
    "SUNDAY",
    };
    string[] RANDOMNM = new string[]
    {
    "CHO","PARK","JIN",
    };
    string CHKDateFormat = "yyyy-MM-dd";

    const int MAX_CNT = 1024;
    string[] CHKNM = new string[MAX_CNT];
    string[] CHKDT = new string[MAX_CNT];
    string[] CHKYO = new string[MAX_CNT];
    string[] CHKRM = new string[MAX_CNT];

    string MANUAL_DT = "20230101121212";

    public void CALCCHK()
    {
        int ii = 0; //(1-MON, 7-SUNDAY)
        int day = 0;
        int mm = 0;
        int kk = 0;

        DateTime now = DateTime.ParseExact(MANUAL_DT, "yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture);

        DateTime calcnow;

        //POINT:CHKRM's INCREASE ITSELF
        //POINT:RANDOMNM's INCREASE ITSELF
        //POINT:CHKRM's INCREASE ITSELF
        //POINT:RANDOMNM's INCREASE ITSELF

        while (true)
        {
            calcnow = now.AddDays(day);
            if (Convert.ToInt32(calcnow.ToString(CHKDateFormat).Replace("-", "")) < 20231231)
            {
                day++;
                continue;
            }
            if (Convert.ToInt32(calcnow.ToString(CHKDateFormat).Replace("-", "")) == 20250101) break;
            if (Convert.ToInt32(calcnow.ToString(CHKDateFormat).Replace("-", "")) == 20231231) ii = 7;




            int check = 0;
            for (int ff = 0; ff < HOLIDAY.Length; ff++)
            {
                if (calcnow.ToString(CHKDateFormat) == HOLIDAY[ff])
                {
                    check = 100;
                    break;
                }
            }


            if (check == 0)
            {
                if (ii == 4) CHKRM[kk++] = RANDOMNM[mm++ % 3];
                else if (ii == 5) CHKRM[kk++] = RANDOMNM[mm++ % 3];
            }
            else
            {
                if (ii == 1) CHKRM[kk++] = "PARK";
                else if (ii == 2) CHKRM[kk++] = "JIN";
                else if (ii == 3) CHKRM[kk++] = "CHO";
                else if (ii == 4) CHKRM[kk++] = RANDOMNM[mm++ % 3];
                else if (ii == 5) CHKRM[kk++] = RANDOMNM[mm++ % 3];
            }

            day++;
            ii++;

            if (ii == 8) ii = 1;
        }
    }
    public void REALCHK()
    {
        int ii = 0; //(1-MON, 7-SUNDAY)
        int day = 0;
        int kk = 0;
        int sum = 0;

        DateTime now = DateTime.ParseExact(MANUAL_DT, "yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture);
        DateTime calcnow;

        while (true)
        {
            calcnow = now.AddDays(day);
            if (Convert.ToInt32(calcnow.ToString(CHKDateFormat).Replace("-", "")) < 20231231)
            {
                day++;
                continue;
            }
            if (Convert.ToInt32(calcnow.ToString(CHKDateFormat).Replace("-", "")) == 20250101) break;
            if (Convert.ToInt32(calcnow.ToString(CHKDateFormat).Replace("-", "")) == 20231231) ii = 7;




            int check = 0;
            for (int ff = 0; ff < HOLIDAY.Length; ff++)
            {
                if (calcnow.ToString(CHKDateFormat) == HOLIDAY[ff])
                {
                    check = 100;
                    break;
                }
            }


            if (check == 0)
            {
                if (ii == 1)
                {
                    CHKNM[sum] = "PARK";
                    CHKYO[sum] = YOIL[ii - 1];
                    CHKDT[sum] = calcnow.ToString(CHKDateFormat);
                }
                else if (ii == 2)
                {
                    CHKNM[sum] = "JIN";
                    CHKYO[sum] = YOIL[ii - 1];
                    CHKDT[sum] = calcnow.ToString(CHKDateFormat);
                }
                else if (ii == 3)
                {
                    CHKNM[sum] = "CHO";
                    CHKYO[sum] = YOIL[ii - 1];
                    CHKDT[sum] = calcnow.ToString(CHKDateFormat);
                }
                else if (ii == 4)
                {
                    CHKNM[sum] = CHKRM[kk++];
                    CHKYO[sum] = YOIL[ii - 1];
                    CHKDT[sum] = calcnow.ToString(CHKDateFormat);
                }
                else if (ii == 5)
                {
                    CHKNM[sum] = CHKRM[kk++];
                    CHKYO[sum] = YOIL[ii - 1];
                    CHKDT[sum] = calcnow.ToString(CHKDateFormat);
                }
                else if (ii == 6)
                {
                    CHKNM[sum] = "HOLIDAY";
                    CHKYO[sum] = YOIL[ii - 1];
                    CHKDT[sum] = calcnow.ToString(CHKDateFormat);
                }
                else if (ii == 7)
                {
                    CHKNM[sum] = "HOLIDAY";
                    CHKYO[sum] = YOIL[ii - 1];
                    CHKDT[sum] = calcnow.ToString(CHKDateFormat);
                }
            }
            else if (check == 100)
            {
                CHKYO[sum] = YOIL[ii - 1];
                CHKDT[sum] = calcnow.ToString(CHKDateFormat);

                int subcheck = 0;
                for (int ff = 0; ff < HOLIDAY.Length; ff++)
                {
                    if (CHKDT[sum] == HOLIDAY[ff])
                    {
                        CHKNM[sum] = HOLIDAYNM[ff];
                        subcheck = 100;
                        break;
                    }
                }
                if (subcheck == 0)
                {
                    CHKNM[sum] = "SPECIAL";
                }
            }

            day++;
            ii++;
            sum++;

            if (ii == 8) ii = 1;
        }
    }
    public void DISPCHK()
    {
        int kk = 0;
        int ____park_k = 0, ____jin_k = 0, ____cho_k = 0;

        while (true)
        {
            string dateTxt = "";
            string nameTxt = "";

            int check = 0;
            for (int ii = 0; ii < 7; ii++)
            {
                dateTxt += CHKDT[kk] + " ";
                nameTxt += CHKNM[kk] + " ";

                if (CHKNM[kk] == "PARK") ____park_k++;
                else if (CHKNM[kk] == "JIN") ____jin_k++;
                else if (CHKNM[kk] == "CHO") ____cho_k++;

                if (CHKDT[kk] == "2024-12-31")
                {
                    check = 100;
                    break;
                }

                kk++;
            }
            Console.WriteLine(dateTxt);
            Console.WriteLine(nameTxt);

            if (check == 100) break;
        }
    }
}







'c# 언어 > 초급과정' 카테고리의 다른 글

프로세스.종료  (0) 2024.03.16
DispatcherTimer 활용사례  (0) 2024.03.12
SetWindowLong 함수란 무엇인가  (0) 2024.01.30
Windows Form 실행시에 Message 순서출력  (0) 2024.01.06
공백여러개를 하나로 정리하기  (0) 2023.12.13

Compute Unified Device Architecture

NVIDIA가 만든 GPGPU 플랫폼 및 API 모델이다.

CUDA 플랫폼은 GPU의 가상 명령어셋을 사용할 수 있도록 만들어주는 소프트웨어 레이어이며, NVIDIA가 만든 CUDA 코어가 장착된 GPU에서 작동한다. 발빠른 출시 덕분에 수 많은 개발자들을 유입시켜, 사실상 엔비디아 생태계의 핵심으로 불린다. 물론 GPU 성능 차이도 있지만, 딥러닝이 각각 2012년[2]과 2016년[3]에 제대로 터지기 전부터 빠른 선구안을 취하여 업계 개발자들을 해당 플랫폼에 락인시킨 것이 매우 크다.[4]

2006년 11월에 G80 마이크로아키텍처와 함께 처음 발표된 후, 2007년 6월 23일에 CUDA SDK가 처음 배포되었다. 초기에는 C, C++만 지원했지만 10여 년이 지난 지금은 포트란이나 C#등 다양한 언어에서 사용이 가능하다. 그러나 기본적인 구조 자체는 CUDA를 설치할 때 설치되는 전용 CUDA 컴파일러가 cuda 코드 파일을 컴파일하고, 그 다음에 C++나 C# 같은 기존 언어 컴파일러에 결과물을 투입하는 방식. 버전 정보는 이곳에서 확인할 수 있다.

새로운 마이크로아키텍처 혹은 새로운 GPU가 나올 때마다 CUDA Compute Capability가 올라갔기 때문에 오래된 GPU의 경우 CUDA Compute Capability가 낮아서 일부 CUDA 기반 응용프로그램과 호환이 안될 수 있으나, 과거에 개발된 CUDA 기반 응용프로그램은 최신 GPU에서도 잘 작동한다. 또한, CUDA가 대두되면서 2007년에 GPGPU 전용인 TESLA[5] 제품군이 나왔는데, TESLA 제품군은 ECC 메모리를 탑재하여 메모리 오류를 정정하며, GeForce에서 쓰이는 같은 아키텍처 칩셋이라도 추가 명령어 몇 개를 더 지원한다. 다만 차세대 아키텍처의 GeForce에선 이전 세대의 CUDA 명령어를 전부 흡수하여 지원하는 경향이 있으므로 최신 GeForce 제품을 써도 이전 세대의 Tesla 전용 명령어를 쓸 수 있다.

GPU에 따른 CUDA Compute Capability는 이 링크를 참고하면 되며, 아래는 아키텍처 또는 GPU별로 대략적으로 정돈하였다. CUDA SDK 버전과는 다르므로 구분할 때 주의할 것.
G80 : 1.0
G84, G86, G92, G94, G96, G98 : 1.1
GT215, GT216, GT218 : 1.2
GT200 : 1.3
Fermi : 2.0~2.1
Kepler 1.0 : 3.0~3.7
Kepler 2.0 : 3.5~3.7
Maxwell 1.0 : 5.0~5.3
Maxwell 2.0 : 5.2~5.3
Pascal : 6.0~6.2
Volta : 7.0
Turing : 7.5
Ampere: 8.0

CUDA와 비슷한 GPGPU 기술로 OpenCL과 DirectCompute가 있지만 이들은 표준을 기준으로 만들어졌기 때문에 로우 레벨 API의 하드웨어에 있는 고급 기능까지 사용하여 한계까지 성능을 끌어내긴 어렵다. 즉, 다른 기술은 D3D API 등을 경유하기 때문에 시간이 걸리지만 쿠다는 바로 하드웨어에 엑세스하여 컨트롤할 수 있다.

하지만 이는 쿠다의 단점으로 이어지는데, 그래픽 기능과의 연동을 전제로 만들어진 DirectCompute에 비해 그래픽 출력 용도로 사용시 오버헤드가 커진다.

그래픽 카드의 GPU는 대량의 데이터에 한 가지 연산을 적용하는 경우가 많기 때문에 단순화된 연산 유닛(코어)을 천여 개씩 탑재하고 있다.[6] 따라서 SIMD(Single Instruction Multiple Data) 형태의 병렬화가 가능한 연산에 GPU를 활용해서 속도를 올리려는 시도는 예전부터 있어 왔다. 그러나 원래 그래픽을 처리하라고 설계된 그래픽스 파이프라인을 가지고 일반적인 병렬 연산을 수행하는 것은 매우 골치아픈 일이었다. 프로그래머가 일일이 GPU의 세부 사항을 다 신경써야 했기 때문이다.

CUDA 프로그램은 스트림 프로세싱[7]에 기반하며, 그 작성에는 C/C++ 언어에 동시에 실행할 쓰레드 개수 등을 선언하는데 사용되는 CUDA 전용 문법을 추가한 언어를 사용한다. CUDA 코드는 대략 GPU 안에서만 돌아가는 함수(커널이라고 부른다)를 호스트(CPU)에서 호출하는 형태로 되어 있다.

CUDA는 GPU의 메모리 모델을 추상화해서 좀 더 편하게 GPU를 이용할 수 있도록 했다. 하지만 여전히 CUDA로 최대한의 속도 증가를 얻으려면 GPU의 메모리 구조에 대해서 잘 알아야 한다. 윈도우 한정으로 CUDA 프로그래밍의 귀찮음을 덜어 주기 위해서 만들어진 BSGP(Bulk-Synchronous GPU Programming)라는 녀석이 존재한다. BSGP는 CUDA의 기계어 명령번역을 사용한 별도 언어다. 레이 트레이싱 류의 coherence가 낮은 작업에선 CUDA보다 성능향상이 있다. 다만 BSGP가 만능은 아니다. 반대로 메모리 참조 연속성이 강한 작업에선 CUDA보다 성능이 낮아진다.

최근에 CUDA를 더 보완한 OpenACC라는 게 나왔다. 좀 더 추상화가 돼있어서 코딩하기 더 편하다고 한다. 마이크로소프트에서는 C++ AMP라는 걸 만들었는데 OpenACC의 DirectCompute 버전 정도라 볼 수 있다. 그래도 아직은 일반 프로그래머가 사전지식 없이 덤빌 만한 난이도는 아니다. 단지 전에 비해 진입장벽이 많이 낮아졌을 뿐.

R337 드라이버 이후부터는 Geforce 제품군에서의 CUDA 기반 비디오 인코딩/디코딩 라이브러리가 삭제되었다. NVENC[8]를 밀기 위해서라는데(이전의 쿠다 인코더를 대체) Tesla나 Quadro 제품군은 정상적으로 사용이 가능하다. 이에 CUDA 가속을 사용하는 코덱의 사용이 불가능해지거나, 이전의 라이브러리 파일을 따로 넣지 않으면 미디어 편집 프로그램들에서의 호환성에 문제가 생겼다. 황사장: 꼬우면 쿼드로 사시든가

딥러닝을 도와주는 여러 라이브러리도 CUDA와 함께 제공된다. cuDNN, Convolution 연산을 더 빠르게 만들어주는 cuFFT[9], 선형대수 모듈인 cuBLAS 등 사실상 필요한 라이브러리들은 대부분 구현되어 있다. 하지만 그래도 사용은 어렵다. TensorFlow나 PyTorch 프레임워크가 이와 같은 라이브러리들을 사용한다.

인공지능을 위한 GPU(CUDA 설치)

 인공지능, 블록체인, GPU
"인공지능 코드를 테스트해보려면 GPU가 좋아야 해.', '인공지능을 위해 개발된 GPU'
'비트코인으로 인한 GPU 대란' 등의 이야기를 심심찮게 들어봤을 것이다. 인공지능와 블록체인에는 왜 GPU로 연산을 하는 것일까?

인공지능과 블록체인은  '쉬운 연산을 엄청나게 많이' 해야 하기 때문이다.
다음 영상을 보면 아주 쉽게 이해될 것이다.

인공지능은 행렬 연산을 엄청나게 많이 해야 하고 블록 체인은 엄청나게 많은 무작위 숫자(난수)를 대입해야 한다. 따라서 좋은 GPU는 연산 시간을 줄이는데 매우 유용하다.
 GPGPU(General-Purpose computing on Grphics Processing Unit)
원래 GPU의 목적은 CPU의 보조 장치로써 그래픽 처리만 담당했다. 하지만 이후 GPU가 행렬과 벡터 연산에 유용하게 쓰일 수 있다는 점에서 착안해 CPU 대신 GPU로 그래픽 처리 뿐만 아니라 행렬, 벡터 처리까지 가능하도록 만든 것이다. 이렇게 일반적인 목적의 연산(General-Purpose computing)도 처리하는 GPU를 GPGPU 라고 부른다.
그 덕분에 인공지능 학습 속도가 과거에 비해 크게 향상되었다.
필자도 인공지능 공부를 위해 좋은 GPU를 구입해서 파이토치를 구동시켜봤다.
GPU가 일을 하고 있나 확인하기 위해 작업관리자로 확인을 해봤다.

사실 GPU를 사용하기 위해서는 GPU를 사용하기 위한 프로그램을 설치해야 한다.
우리가 GPU를 사용하자고 컴퓨터에 알려주지 않았기 때문에 러닝을 돌리면 컴퓨터는 CPU로 연산을 한다.
아래부터는 CUDA라는 프로그램을 설치하는 방법에 대한 글입니다. 현재 설치할 계획이 없으시다면 건너뛰어도 괜찮습니다! 단순 호기심에 설치하다가는 하루를 그냥 날려버릴 수도 있어요!


CUDA
GPU로 러닝을 돌리기 위해 사용하는 프로그램이 바로 이 CUDA이다.
CUDA는 GPU 제조회사로 유명한 'NVIDIA' 회사용 프로그램이다. (GPU가 NVIDIA 외 다른 회사라면 다른 프로그램을 사용해야 함.)
아래는 설치방법이다. 그 외에도 설치방법은 인터넷에 검색하면 쉽게 찾을 수 있다.

꼭 드라이버 설치 → CUDA 설치 → cuDNN 설치 순서로 진행하자.
설치 전에 설치할 tensorflow 버전, 파이썬 버전, CUDA버전, cuDNN버전이 서로 호환되는지 꼭 확인하고 설치하자!! (정말 매우매우 중요하다. 이거 잘못하면 삽질의 늪에 빠진다.)

GPU 드라이버 호환 확인
GPU 드라이버 설치 후 cmd 창에 nvidia-smi 라고 쳤을 때 Driver Version 값이 높을 수록 좋다. (여기서 (Driver Version에 나오는 숫자는 최대로 설치할 수 있는 버전을 의미한다.
텐서플로우와 호환성을 따져보고 더 낮은 버전을 설치해도 괜찮다.)
예를들어 CUDA11.4.0GA 버전의 툴킷은 Driver Version 값이 471.11(윈도우 기준) 이상이어야 설치해도 문제 없다는 의미이다.

나머지 버전 호환
본인이 설치할 수 있는 CUDA 버전을 확인한 후 그에 맞게 텐서플로우, 파이썬, cuDNN 버전을 맞추면 된다. 
(가능하면 conda 가상환경에서 사용하는 것을 추천한다.)
설치가 잘 되었다면 nvcc -V 명령어로 잘 설치되었는지 확인할 수 있다. 
이 명령어가 실행되지 않으면 잘못 설치한 것이다.

정리
개발환경을 세팅하는 것은 귀찮고 어렵다. 특히 CUDA같은 경우 인공지능 프레임워크와 GPU간의 호환이 전부 맞아 떨어져야 사용이 가능하다. 
필자도 다시 지우고 깔기를 엄청 반복했다.
좋은 GPU를 사놓고 CUDA 설정을 못해서 CPU로 인공지능 공부하는 사람이 없어야 한다.

[DirectX 12] 기본지식 - CPU / GPU 동기화


한 시스템에 CPU와 GPU가 병렬로 실행되다 보니 동기화 문제가 발생한다. 
예를 들어 그리고자 하는 어떤 기하구조의 위치를 R이라는 자원에 담는다고 하자. 
그 기하구조를 위치 p1에 그리려는 목적으로 CPU는 위치 p1을 R에 추가하고, R을 참조하는 그리기 명령 C를 명령 대기열에 추가한다.

명령 대기열에 명령을 추가하는 연산은 CPU의 실행을 차단하지 않으므로, CPU는 계속해서 다음 단계로 넘어간다. 
만약 GPU가 그리기 명령 C를 실행하기 전에 CPU가 새 위치 p2를 R에 추가해서 R에 있던 기존 p1을 덮어쓰면, 기하구조는 의도했던 위치에 그려지지 않게 된다.

이런 문제의 해결책은 GPU가 명령 대기열의 명령들 중 특정 지점까지의 모든 명령을 다 처리할 때까지 CPU를 기다리게 하는 것이다. 
대기열의 특정 지점까지의 명령을 처리하는 것을 가리켜 명령 대기열을 비운다 또는 방출한다(Flush)라고 말한다.

이때 필요한 것이 바로 울타리(Fence)이다. 
울타리(펜스)는 ID3D12Fence 인터페이스로 대표되며, GPU와 CPU의 동기화를 위한 수단으로 쓰인다. 
다음은 펜스 객체를 생성하는 메서드이다.


사용 예)
m_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, 
__uuidof(ID3D12Fence), (void**)&m_pd3dFence);

펜스 객체는 UINT64 값 하나를 관리한다. 이 값은 시간상의 특정 펜스 지점을 식별하는 정수이다. 이 값을 0으로 두고, 새 펜스 지점을 만들 때마다 이 값을 1씩 증가시킨다. UINT64의 최대값은 엄청나게 큰 값이기 때문에(약 1.8천경 정도 된다) 아무리 많은 시간동안 게임을 실행하며 이 값을 1씩 증가시킨다고 해도 이 값이 최대 값을 넘어간다는 걱정은 하지 않아도 된다.

다음은 펜스를 이용해서 명령 대기열을 비우는 방법을 보여주는 코드이다.
// 현재 펜스 지점까지의 명령들을 표시하도록 펜스 값을 전진
m_nFenceValue++;

// 새 펜스 지점을 설정하는 명령을 명령 대기열에 추가한다.
m_pd3dCommandQueue->Signal(m_pd3dFence, m_nFenceValue);

// GPU가 이 펜스 지점까지의 명령들을 완료할 때까지 기다린다.
if(m_pd3dFence->GetCompletedValue() < m_nFenceValue)
{
// GPU가 현재 펜스 지점에 도달했으면 이벤트를 발동시킨다.
m_pd3dFence->SetEventOnCompletion(m_nFenceValue, m_hFenceEvent);

// GPU가 현재 펜스 지점에 도달했음을 뜻하는 이벤트를 기다린다.
::WaitForSignalObject(m_hFenceEvent, INFINITE);
}
이 코드를 도식화하면 다음과 같다.(생략)


위 숫자 순으로 보면 어떤 순서로 돌아가는지 알 수 있을것이다. 
GPU는 현재 프레임에서 필요한 명령들을 완료하면 펜스 객체의 값을 하나 증가시키는 명령을 실행하게 된다. 
CPU는 그 작업을 하기 전까지 대기하는 것이다.

반응형

(adsbygoogle = window.adsbygoogle || []).push({});

window.ReactionButtonType = 'reaction';
window.ReactionApiUrl = '//lipcoder.tistory.com/reaction';
window.ReactionReqBody = {
entryId: 54
}

GC(Garbage Collection)는 객체가 더 이상 사용되지 않을 때 자동으로 메모리에서 제거하는 기능입니다. 하지만 GC에도 몇 가지 문제점이 있습니다.

  1. 성능 저하: GC는 메모리를 정리하기 위해 일정 시간 동안 애플리케이션의 실행을 중단 시키며, 이로 인해 애플리케이션의 성능이 저하 될 수 있습니다. 특히 대용량 데이터를 처리하는 경우에는 GC로 인한 성능 저하가 더욱 두드러질 수 있습니다.
  2. 메모리 누수: GC가 모든 객체를 완벽하게 제거하지 못할 경우 메모리 누수가 발생할 수 있습니다. 메모리 누수는 애플리케이션이 사용할 수 있는 메모리를 감소시키고, 시스템의 성능을 저하시킬 수 있습니다.
  3. 예측 불가능성: GC의 실행 시점은 예측하기 어렵습니다. 이로 인해 애플리케이션의 안정성이 떨어질 수 있습니다.
  4. 과도한 메모리 사용: GC는 메모리를 자동으로 관리하기 때문에 개발자가 메모리 사용량을 정확하게 제어하기 어렵습니다. 이로 인해 과도한 메모리 사용이 발생할 수 있습니다.

이러한 문제점을 해결하기 위해서는 적절한 GC 알고리즘을 선택하고, 메모리 사용량을 모니터링하고, 메모리 관리 전략을 수립하는 등의 노력이 필요합니다.

Sample.File.Explorer/Source

*.Designer.cs 부분 소스
this.treeView1.BeforeCollapse += new Systehttp://m.Windows.Forms.TreeViewCancelEventHandler(this.treeView1_BeforeCollapse);
this.treeView1.BeforeExpand += new Systehttp://m.Windows.Forms.TreeViewCancelEventHandler(this.treeView1_BeforeExpand);
this.treeView1.NodeMouseClick += new Systehttp://m.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick);

 

 

      

 

*.cs 부분 소스

private void Form1_Load(object sender, EventArgs e)
        {
            //현재 사용자 정보 표시
            System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
            label1.Text = "현재 사용자  :" + identity.Name;

            //현재 로컬 컴퓨터에 존재하는 드라이브 정보 검색하여 트리노드에 추가
            DriveInfo[] allDrives = DriveInfo.GetDrives();

            foreach (DriveInfo dname in allDrives)
            {
                if (dname.DriveType == DriveType.Fixed)
                {
                    if (dname.Name == @"C:\")
                    {
                        TreeNode rootNode = new TreeNode(dname.Name);
                        rootNode.ImageIndex = 0;
                        rootNode.SelectedImageIndex = 0;
                        treeView1.Nodes.Add(rootNode);
                        Fill(rootNode);
                    }
                    else
                    {
                        TreeNode rootNode = new TreeNode(dname.Name);
                        rootNode.ImageIndex = 1;
                        rootNode.SelectedImageIndex = 1;
                        treeView1.Nodes.Add(rootNode);
                        Fill(rootNode);
                    }
                }
            }

            //첫번째 노드 확장
            treeView1.Nodes[0].Expand();

            //ListView 보기 속성 설정
            listView1.View = View.Details;

            //ListView Details 속성을 위한 헤더 추가
            listView1.Columns.Add("디렉토리.이름", listView1.Width / 5, HorizontalAlignment.Left);
            listView1.Columns.Add("이름", listView1.Width / 5, HorizontalAlignment.Left);
            listView1.Columns.Add("수정한 날짜", listView1.Width / 5, HorizontalAlignment.Left);
            listView1.Columns.Add("유형", listView1.Width / 5, HorizontalAlignment.Left);
            listView1.Columns.Add("크기", listView1.Width / 5, HorizontalAlignment.Left);

            //행 단위 선택 가능
            listView1.FullRowSelect = true;
        }
        /// <summary>
        /// 트리를 마우스로 클릭할 때 발생하는 이벤트
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            try
            {
                //기존의 파일 목록 제거
                listView1.Items.Clear();
                DirectoryInfo dir = new DirectoryInfo(e.Node.FullPath);

                int DirectCount = 0;
                //하부 데렉토르 보여주기
                foreach (DirectoryInfo dirItem in dir.GetDirectories())
                {
                    //하부 디렉토리가 존재할 경우 ListView에 추가
                    //ListViewItem 객체를 생성
                    ListViewItem lsvitem = new ListViewItem();

                    //생성된 ListViewItem 객체에 똑같은 이미지를 할당
                    lsvitem.ImageIndex = 2;
                    lsvitem.Text = dirItem.Name;

                    //아이템을 ListView(listView1)에 추가
                    listView1.Items.Add(lsvitem);
                    listView1.Items[DirectCount].SubItems.Add("");

                    listView1.Items[DirectCount].SubItems.Add(dirItem.CreationTime.ToString());
                    listView1.Items[DirectCount].SubItems.Add("폴더");
                    listView1.Items[DirectCount].SubItems.Add(dirItem.GetFiles().Length.ToString() + " files");
                    DirectCount++;
                }

                //디렉토리에 존재하는 파일목록 보여주기
                FileInfo[] files = dir.GetFiles();
                int Count = 0;
                foreach (FileInfo fileinfo in files)
                {
                    listView1.Items.Add(fileinfo.FullName);
                    listView1.Items[Count].SubItems.Add(fileinfo.Name);

                    if (fileinfo.LastWriteTime != null)
                    {
                        listView1.Items[Count].SubItems.Add(fileinfo.LastWriteTime.ToString());
                    }
                    else
                    {
                        listView1.Items[Count].SubItems.Add(fileinfo.CreationTime.ToString());
                    }
                    listView1.Items[Count].SubItems.Add(fileinfo.Attributes.ToString());
                    listView1.Items[Count].SubItems.Add(fileinfo.Length.ToString());
                    Count++;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("에러 발생 : " + ex.Message);
            }
            treeView1.Nodes[0].Expand();
        }

        private void Fill(TreeNode dirNode)
        {
            try
            {
                DirectoryInfo dir = new DirectoryInfo(dirNode.FullPath);
                //드라이브의 하위 폴더 추가
                foreach (DirectoryInfo dirItem in dir.GetDirectories())
                {
                    TreeNode newNode = new TreeNode(dirItem.Name);
                    newNode.ImageIndex = 2;
                    newNode.SelectedImageIndex = 2;
                    dirNode.Nodes.Add(newNode);
                    newNode.Nodes.Add("*");
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("에러 발생 : " + ex.Message);
            }
        }
        /// <summary>
        /// 트리가 확장되기 전에 발생하는 이벤트
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (e.Node.Nodes[0].Text == "*")
            {
                e.Node.Nodes.Clear();
                e.Node.ImageIndex = 3;
                e.Node.SelectedImageIndex = 3;
                Fill(e.Node);
            }
        }
        /// <summary>
        /// 트리가 닫히기 전에 발생하는 이벤트
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            if (e.Node.Nodes[0].Text == "*")
            {
                e.Node.ImageIndex = 2;
                e.Node.SelectedImageIndex = 2;
            }
        }

+ Recent posts