Windows에서 Git 사용 시 Fatal: unsafe repository. is owned by someone else. 에러 해결 방법에 대해 알아봅니다.

 

 

 

1. 현상

 

Windows OS에서 Git 사용 시 다음과 같은 에러가 발생합니다.

 

 

Fatal: unsafe repository. ...is owned by someone else. To add an exception for this directory call:...

 

 

 

2. 원인

 

Git에서 보안 취약점이 발표되었습니다. 자세한 내용은 다음 글을 참조해 주세요: Git security vulnerability announced

 

Git security vulnerability announced | The GitHub Blog

Upgrade your local installation of Git, especially if you are using Git for Windows, or you use Git on a multi-user machine.

github.blog

 

 

 

3. 수정.

 

우선 Git을 업데이트하고 다음 명령어를 통해 해당 폴더를 안전한 폴더로 지정합니다.

 

git config --global --add safe.directory {YOUR_DERECTORY_HERE}

 

 

 

4. 테스트

 

이제 Repository를 조회해 정상적으로 보이는지 확인합니다.

 

 

** 만약 동일한 오류가 계속 반복된다면 Backslash(\) 대신 Slash(/)를 사용해 경로를 지정해 보시기 바랍니다.

 

 

 

반응형

 

The server's host key is not cached. You have no guarantee that the server is the computer you think it is. 문제가 발생한 경우 해결 방법을 알아봅니다.

 

 

 

1. 현상

 

Bitbucket을 사용하기 위해 SourceTree로 Repository에 연결하면 다음과 같은 에러가 발생합니다.

 

 

Command: git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks ls-remote 


출력: 
오류: The server's host key is not cached. You have no guarantee that the server is the computer you think it is.
The server's rsa2 key fingerprint is: 
If you trust this host, enter "y" to add the key to PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the connection.
Store key in cache? (y/n, Return cancels connection, i for more info) fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.

 

 

2. 수정

 

호스트의 키를 캐시 해야 합니다. putty의 plink.exe를 실행시켜 호스트를 캐시 해줍니다.

 

 

 

 

3. 테스트

 

이제 정상적으로 Repository에 접근할 수 있습니다.

 

 

 

 

 

 

반응형

 

SSH 연결 시 UNPROTECTED PRIVATE KEY FILE 에러 해결 방법에 대해 알아봅니다.

 

 

 

1. 현상

 

AWS에서 생성한 키 파일을 사용해 ssh 연결을 시도할 때 UNPROTECTED PRIVATE KEY FILE에러와 함께 접속에 실패하는 현상.

 

 

 

 

2. 수정

 

pem 파일의 권한을 수정해줘야 합니다. 다음과 같이 권한을 수정합니다.

 

 

이후 사용자 유저 하나만 추가해 다음과 같이 만듭니다.

 

 

 

 

3. 접속 테스트

 

이제 다시 접속을 시도해 봅니다.

 

 

정상적으로 접속이 되는 것을 확인할 수 있습니다.

 

 

 

 

 

반응형

 

Entity Framework를 사용해 JOIN 쿼리문을 수행하는 방법에 대해 알아봅니다.

 

 

 

0. 소스코드

 

소스코드는 다음 링크에서 확인할 수 있습니다: https://github.com/smoh-dev/EF_Join

 

GitHub - smoh-dev/EF_Join: https://smoh.tistory.com/471

https://smoh.tistory.com/471. Contribute to smoh-dev/EF_Join development by creating an account on GitHub.

github.com

 

 

 

1. DB 준비

 

MySQL을 설치 한 뒤 다음과 같은 쿼리문을 수행해 테이블을 생성합니다.

 

#Create user table
CREATE TABLE `dev_db`.`tbl_user` (
  `key` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(64) NULL,
  PRIMARY KEY (`key`));

#Create order table.
CREATE TABLE `dev_db`.`tbl_order` (
  `key` INT NOT NULL AUTO_INCREMENT,
  `user_key` INT NOT NULL,
  `code` VARCHAR(128) NOT NULL,
  PRIMARY KEY (`key`),
  INDEX `fk_user_key_idx` (`user_key` ASC),
  CONSTRAINT `fk_user_key`
    FOREIGN KEY (`user_key`)
    REFERENCES `dev_db`.`tbl_user` (`key`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);

#Insert default data.
INSERT INTO `dev_db`.`tbl_user`(`name`) VALUES ('smoh');
INSERT INTO `dev_db`.`tbl_order`(`user_key`, `code`) VALUES (1, 'my-custom-order-id');

 

 

 

 

2. 프로젝트 생성.

 

편의를 위해 간단한 프로젝트를 생성합니다.

 

 

 

 

 

3. NuGet 패키지 설치.

 

다음 NuGet 패키지를 설치합니다.

 

 

 

 

4. Table Model 생성

 

앞서 생성한 테이블대로 모델을 생성합니다.

 

//TableUser
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace my_test_api.Model
{
    [Table("tbl_user")]
    public class TableUser
    {
        [Key]
        [Column("key")]
        public int Key { get; set; }
        [Column("name")]
        public string Name { get; set; }
    }
}

//TableOrder
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace my_test_api.Model
{
    [Table("tbl_order")]
    public class TableOrder
    {
        [Key]
        [Column("key")]
        public int Key { get; set; }
        [Column("user_key")]
        public int UserKey { get; set; }
        [Column("code")]
        public string Code { get; set; }
    }
}

 

 

 

5. DB Context 생성

 

이제 DB Context를 생성해 서비스에 연결합니다.

 

//DBContext
using Microsoft.EntityFrameworkCore;
using my_test_api.Model;
namespace my_test_api
{
    public class DBContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            var connectionString = "server=localhost; database=dev_db; user=dev; password=devpass";
            options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
        }
        public DbSet<TableUser> User { get; set; }
        public DbSet<TableOrder> Order { get; set; }
    }
}

 

//Program.cs
using my_test_api;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

//Add DBContext
builder.Services.AddSingleton<DBContext>();

var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();

 

 

 

6. 컨트롤러 작성

 

다음 코드와 같이 간단한 컨트롤러를 작성합니다.

 

//UserOrderController.cs
using Microsoft.AspNetCore.Mvc;
using my_test_api.Model;
namespace my_test_api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserOrderController : ControllerBase
    {
        DBContext dbContext;
        public UserOrderController(DBContext dBContext)
        {
            this.dbContext = dBContext;
        }
        // GET api/<UserOrderController>/1
        [HttpGet("{id}")]
        public string Get(int id)
        {
            var query = (from u in dbContext.Set<TableUser>()
                        join o in dbContext.Set<TableOrder>()
                        on u.Key equals o.UserKey
                        where u.Key == id
                        select new { u, o }).SingleOrDefault();
            string result = $"UserKey: {query.u.Key}, UserName: {query.u.Name}, OrderKey: {query.u.Key}, OrderCode: {query.o.Code}";
            return result;
        }
    }
}

 

내부의 query를 통해 DB Table Join 작업을 수행합니다.

 

 

 

7. 테스트

 

이제 Swagger를 열고 테스트를 진행해 봅시다.

 

 

쿼리가 정상적으로 동작해 데이터가 출력되는 것을 확인할 수 있습니다.

 

 

 

 

 

반응형

 

 

dotNet 6.0 프로젝트에서 EntityFramework를 사용해 MariaDB에 연결하는 방법에 대해 알아봅니다.

 

 

 

1. NuGet 패키지 설치.

 

다음 NuGet 패키지를 설치합니다.

 

 

 

 

2. DB 테이블 생성

 

DB에 접속해 다음 예시와 같이 테이블을 생성합니다.

 

CREATE TABLE `dev_db`.`users` (
  `Key` INT NOT NULL AUTO_INCREMENT,
  `Id` VARCHAR(128) NOT NULL,
  `Name` VARCHAR(64) NOT NULL,
  PRIMARY KEY (`Key`),
  UNIQUE INDEX `Key_UNIQUE` (`Key` ASC) VISIBLE,
  UNIQUE INDEX `Id_UNIQUE` (`Id` ASC) VISIBLE);

 

 

 

3. DBContext 생성

 

다음 예시와 같이 Model과 DbContext를 생성합니다.

 

//Model: User
    public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public User(string id, string name)
        {
            this.Id = id;
            this.Name = name;
        }
    }
//DbContext: UserContext
    public class UserContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            var connectionString = "server=localhost; database=dev_db; user=dev; password=devpass"; 
            options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
        }
    }

 

 

 

4. User 추가

 

다음 예시 코드를 실행해 Users 테이블에 User를 추가합니다.

 

// Insert a new user to users table.
using (var context = new UserContext())
{
    context.Users.Add(new User("testID", "testName"));
    context.SaveChanges();
}

 

 

DB에 정상적으로 데이터가 추가된 것을 확인할 수 있습니다.

 

 

 

 

 

반응형

 

 

Gradle 빌드시 Cannot find symbol 오류가 발생하는 원인에 대해 알아봅니다.

** Actual and formal argument lists differ in length 오류도 동일한 원인입니다.

 

 

 

1. 현상.

 

일반적으로 Gradle을 빌드 시스템으로 채용해도 추가 라이브러리는 Maven Repository에서 검색해 추가하게 됩니다. 이제 여기서 Lombok을 검색해 build.gradle에 추가해 봅시다.

 

 

 

이제 빌드를 하면 오류가 발생합니다.

 

 

 

 

2. 수정.

 

먼저 IntelliJ 설정에서 Enable Annotation Processor 항목을 활성화합니다.

 

 

다음으로 build.gradle로 이동해 Lombok에 annotationProcessor 항목을 추가합니다.

 

 

이제 빌드를 수행하면 정상적으로 동작합니다.

 

 

 

 

 

반응형

 

쿠버네티스의 구성에 대해 간략하게 알아봅니다.

 

 

 

1. 용어 정리

 

Container: 앱이 구동되는 환경까지 감싸 실행할 수 있도록 하는 격리 기술.
Container Runtime: 컨테이너를 다루는 도구
Docker: 컨테이너 런타임 중 가장 유명한 것.
Orchestration: 여러 서버에 걸친 컨테이너 및 사용 환경을 관리하는 행위.
Kubernetes: 컨테이너 런타임을 통해 컨테이너를 오케스트레이션 하는 도구.

 

 

 

2. Kubernetes의 역할

 

쿠버네티스의 역할은 컨테이너를 분산 배치, 상태 관리 및 컨테이너의 구동 환경까지 관리해 주는 도구이고, 도커는 컨테이너 런타임 중 하나입니다. 쿠버네티스는 컨테이너를 다루기 위해 도커 이외에도 다양한 컨테이너 런타임을 사용할 수 있습니다.

 

 

 

3. Kubernetes의 구성

 

쿠버네티스는 다음 그림과 같이 구성되어 있으며 크게 컨트롤 플레인 컴포넌트와 노드 컴포넌트로 나뉩니다.

 

https://kubernetes.io/ko/docs/concepts/overview/components/

 

3.1. 컨트롤 플레인(Control Plane) 컴포넌트

 

⇒ kube-apiserver

쿠버네티스 컨트롤 플레인의 프론트 엔드. 예를 들어 쿠버네티스 커맨드 라인 도구인 kubectl을 사용해 각종 명령을 수행할 경우 이 명령은 kube-apiserver로 전송됩니다. 이렇게 전달된 요청에 대하여 kube-apiserver는 이 요청의 처리 흐름에 따라 적절한 컴포넌트로 요청을 전달하는 역할까지 맡고 있습니다.

 

⇒ etcd

쿠버네티스 클러스터가 동작하기 위해서는 클러스터 및 리소스의 구성 정보, 상태 정보 및 명세 정보 등이 필요합니다. etcd는 이를 키-값(key-value) 형태로 저장하는 저장소입니다. 안정적인 동작을 위해 자료를 분산해서 저장하는 구조를 채택하고 있습니다.


⇒ kube-scheduler

쿠버네티스 클러스터는 여러 노드로 구성되어 있으며 기본적인 작업 단위라고 할 수 있는 파드는 여러 노드 중 특정 노드에 배치되어 동작하게 됩니다. 이때 새로 생성된 파드를 감지하여 어떤 노드로 배치할지 결정하는 작업을 스케줄링이라고 해요. 이런 스케줄링을 담당하는 컴포넌트가 kube-scheduler입니다.


⇒ kube-controller-manager

다운된 노드가 없는지, 파드가 의도한 복제(Replicas) 숫자를 유지하고 있는지, 서비스와 파드는 적절하게 연결되어 있는지, 네임스페이스에 대한 기본 계정과 토큰이 생성되어 있는지를 확인하고 적절하지 않다면 적절한 수준을 유지하기 위해 조치하는 역할을 하고 있습니다.

 

3.2. 노드(Node) 컴포넌트

 

⇒ kubelet

쿠블릿(kubelet)은 노드에서 컨테이너가 동작하도록 관리해주는 핵심 요소입니다. 각 노드에서 파드를 생성하고 정상적으로 동작하는지 관리하는 역할을 담당합니다 실제로 우리가 쿠버네티스의 워크로드를 관리하기 위해서 내리는 명령은 쿠블릿을 통해 수행된다고 볼 수 있습니다. 우리가 파드를 관리하기 위해 작성하는 yaml은 kube-apiserver를 통해 쿠블릿에 전달됩니다. 쿠블릿은 전달받은 yaml을 통해 파드를 생성하거나 변경하고 컨테이너가 정상적으로 실행되고 있는지 확인합니다.


⇒ container runtime

컨테이너 런타임은 파드에 포함 된 컨테이너 실행을 실질적으로 담당하는 애플리케이션을 의미합니다. 컨테이너 런타임은 쿠버네티스 구성요소에 기본적으로 포함되어있거나 특정 소프트웨어를 지칭하지 않습니다. 쿠버네티스가 컨테이너를 제어하기 위해 제공하는 표준 규약인 Container Runtime Imterface(CRI)를 준수하며 쿠버네티스와 함께 사용할 수 있는 외부 애플리케이션을 지칭합니다. 이런 CRI를 준수하는 대표적인 컨테이너 런타임은 containerd 혹은 CRI-O 등이 있습니다.


⇒ kube-proxy

kube-proxy는 쿠버네티스 클러스트 내부에서 네트워크 요청을 전달하는 역할을 합니다. 만약 kube-proxy가 없다면 쿠버네티스 내부에 위치한 특정 파드로 요청을 보내기 위해선 파드의 IP를 정확히 알아야 하며 이 IP를 외부에서 접근할 수 있도록 설정해야 합니다. 하지만 파드의 IP는 배포마다 변경되기 때문에 파드의 IP를 이용하는 방법은 쉽지 않습니다. 따라서 이러한 문제를 해결하기 위해 쿠버네티스는 오브젝트를 통해 고정적으로 파드에 접근할 수 있도록 하는 방법을 제공하고 요청이 실제 파드에 접근할 수 있도록 관리합니다. 이 관리를 담당하는 컴포넌트가 kube-proxy입니다.

 

 

 

4. 파드(Pod)

 

https://kubernetes.io/ko/docs/tutorials/kubernetes-basics/explore/explore-intro/

 

파드(Pod)는 쿠버네트스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위입니다. 하나 이상의 컨테이너 그룹을 의미하며 그룹 내 컨테이너는 스토리지 및 네트워크를 공유하게 됩니다. 

 

 

 

5. 워크로드

https://i.redd.it/mmauw9cprt161.png

 

워크로드는 쿠버네티스에서 구동되는 애플리케이션입니다. 워크로드가 단일 컴포넌트든 여러 컴포넌트든 관계없이 쿠버네티스에서는 워크로드를 일련의 파드 집합 내에서 실행합니다. 파드는 클러스터에서 실행 중인 컨테이너 집합을 의미합니다. 파드에는 정의된 라이프사이클이 있으나 사용자가 각 파드를 직접 관리할 필요는 없습니다. 대신 워크로드 리소스를 사용해 파드의 집합을 관리하게 됩니다.

 

 

 

References

 

 

 

 

반응형

 

 

자바 빌드 시스템에 대해 알아봅니다.

 

 

 

1. Maven

 

 

전통적인 빌드 툴입니다. 시작은 Apache ANT의 대안으로 시작되었으며 자바 프로젝트의 전체적인 관리를 가능하게 함과 동시에 많은 편리함과 이점을 제공해 줘 널리 사용되었습니다.

 

Project Object Model을 관리하는 pom.xml 파일을 사용하며 개발자가 해당 파일에 사용할 라이브러리를 정의해 두면 정의된 라이브러리뿐 아니라 그 라이브러리를 사용하는데 필요한 종속된 다른 라이브러리까지 관리해 자동으로 다운로드하여 사용할 수 있게 해 줍니다.

 

빌드 동작 방식이 미리 정해져 있으며 라이프사이클에 의해 순서에 맞게 동작합니다. Maven의 라이프사이클까지 자세히 다루진 않습니다.

 

 

 

2. Gradle

 

 

Gradle 역시 빌드 툴입니다. Maven 보다 늦게 출발한 후발주자입니다. Gradle은 기존 ANT와 Groovy기반으로 구축되어 기존의 ANT 역할과 배포 기능 모두 지원합니다.

 

Gradle은 늦게 만들어진 만큼 Maven에 비해 더 나은 사용성과 성능을 제공하고 있습니다. 안드로이드 앱의 공식 빌드 시스템이기도 하며 Java, C/C++, Python 등 다양한 언어에 대한 빌드를 지원하고 있습니다.

 

Maven과 달리 build.gradle 파일을 사용하며 Maven과 동일하게 개발자가 사용할 라이브러리를 정의해 둘 수 있습니다. Gradle 역시 정의된 라이브러리뿐 아니라 그 라이브러리를 사용하는데 필요한 종속된 다른 라이브러리까지 관리해 자동으로 다운로드하여 사용할 수 있게 해 줍니다.

 

 

 

3. Maven vs Gradle

 

사실 두 빌드 시스템은 자주 비교되곤 합니다. 성능과 편의성면에서는 당연히 Gradle의 우세입니다. 나중에 나왔으니 기존 Maven 보다 더 좋게 차별점을 두는 게 당연합니다.

 

당장 라이브러리를 관리하는 것만 봐도 그렇습니다. Maven의 경우 xml로 관리하고 Gradle의 경우 Groovy를 사용해 라이브러리가 많아질수록 관리적 측면과 가독성만 해도 엄청나게 차이 날게 뻔합니다. 심지어 Groovy를 사용해 개발자가 직접 스크립트를 작성해 빌드를 커스텀할 수도 있고 플러그인을 호출할 수도 있습니다.

 

 

성능면에서도 많이 차이가 납니다. 클린 상태에서 빌드도 거의 두배 가량 차이나고 심지어 캐싱된 상태에서는 최대 100배까지 차이가 납니다.

 

다른 다양한 이점도 있지만 여기까지만 들어도 모두가 다 Gradle을 사용하겠구나 생각할 수도 있습니다만 사실 Maven을 더 많이 사용한다고 합니다.

 

 

많은 사람들이 익숙함과 Groovy를 배워야 한다는 생각에 Maven을 사용하고 있을 수도 있습니다. 물론 개발자 포럼에 공유되어 있는 코드가 Maven으로 작성되어 있어서 빠르게 적용하기 위해서 그럴 수도 있습니다. 아니면 회사에서 사용하고 있던 제품 프로젝트의 빌드 시스템이 Maven으로 설정되어 있어서 그럴 수도 있고요.

 

하지만 아무리 생각해봐도 이제 더 이상 Maven을 고집할 이유는 모르겠습니다. 이미 사내에서 관리되고 있는 프로젝트가 아니라면 포럼이나 학습서에 Maven으로 작성되어 있어도 Gradle로 직접 바꿔서 시도해보는 것이 좋다고 생각합니다.

 

 

 

4. IntelliJ

 

 

IntelliJ를 IDE로 사용하고 새로운 Java 프로젝트를 생성할 때 보면 Build System에 Maven과 Gradle보다 IntelliJ라는 항목이 먼저 보였던 것을 기억하나요?

 

 

사실 앞서 다룬 내용처럼 대부분의 사용자는 Maven을 사용할 테고 다시 그 나머지 사용자의 대부분은 Gradle을 사용할 거로 생각합니다. StackOverflow와 같은 사이트를 보면 종종 IntelliJ에 관한 질문이 있긴 합니다. 결론은 "IntelliJ에서 제공해주는 독자적인 빌드 방식"입니다.

 

IntelliJ 빌드 시스템은 IntelliJ의 자체 빌드 메커니즘으로 단순하게 프로젝트의 모든 수정 내용과 종속 파일을 컴파일하는 기능입니다. 여기서 문제는 수정 내용과 종속된 파일만 빌드한다는데 있습니다. 안타깝게도 Maven과 Gradle과 달리 순수하게 빌드를 수행합니다. 그로 인해 아티팩트 생성, 리포지토리 배포, CodeGen과 같은 다른 작업을 수행하지 않습니다.  

 

위와 같은 이유로 인해 대부분의 개발자들은 Maven과 Gradle과 같은 빌드 툴을 사용합니다. 심지어 이 두 툴은 잘 사용한다면 개발자가 직접 지정한 빌드 구성을 설정할 수도 있습니다.

 

 

 

5. References

 

 

 

 

 

 

반응형

 

어느 날 프로토타입 제작을 위해 VS2022에서 새로운 클래스를 생성했는데 기본 한정자가 public에서 internal로 변경되었는지 internal로 생성이 되더군요. 이 기회에 C#에서 사용하고 있는 액세스 한정자에 대해 알아보고 정리해 둡니다.

 

 

 

1. 액세스 한정자 - Access Modifiers

 

모든 형식과 형식 멤버에는 접근성 수준이 있습니다. 접근성 수준은 어셈블리 또는 다른 어셈블리의 다른 코드에서 사용할 수 있는지 여부를 제어합니다. 어셈블리는 단일 컴파일에서 하나 이상의. cs 파일을 컴파일하여 만든. dll 또는. exe입니다. 선언할 때 형식 또는 멤버의 액세스 가능성을 지정하려면 다음과 같은 액세스 한정자를 사용합니다.

 

쉽게 설명하면 한 클래스에서 다른 클래스의 멤버 변수나 함수에 접근할 때 그 접근이 가능한지 여부를 결정짓는 게 액세스 한정자입니다.

 

 

 

2. 액세스 한정자의 종류

 

C#에서 액세스 한정자는 6가지가 있습니다. 6가지는 다음과 같습니다.

  • public: 형식 또는 멤버는 동일한 어셈블리 또는 이를 참조하는 다른 어셈블리의 다른 코드에서 액세스 할 수 있습니다. 형식의 public 멤버에 대한 액세스 가능성 수준은 형식 자체의 액세스 가능성 수준에 의해 제어됩니다.
  • private: 형식 또는 멤버는 동일한 클래스 또는 구조체의 코드에서만 액세스 할 수 있습니다.
  • protected: 유형 또는 멤버는 동일한 클래스 또는 해당 클래스에서 파생된 클래스의 코드에서만 액세스 할 수 있습니다.
  • internal: 동일한 어셈블리의 모든 코드에서 형식 또는 멤버에 액세스 할 액세스 할 수 있지만 다른 어셈블리에서는 액세스 할 수 없습니다. 즉, 내부 형식이나 멤버는 동일한 컴파일의 일부인 코드에서 액세스 할 수 있습니다.
  • protected internal: 형식 또는 멤버는 선언된 어셈블리의 모든 코드에서 또는 다른 어셈블리의 파생 클래스 내에서 액세스 할 수 있습니다.
  • private protected: 포함하는 어셈블리 내에서 선언된 클래스에서 파생된 형식에서 형식 또는 멤버에 액세스할 수 있습니다.

해당 기능을 표로 정리하면 다음과 같습니다.

 

 

 

더욱더 자세한 내용은 다음 페이지를 참고하시면 좋습니다: Access Modifiers (C# Programming Guide)

 

Access Modifiers - C# Programming Guide

All types and type members in C# have an accessibility level which controls whether they can be used from other code. Review this list of access modifiers.

docs.microsoft.com

 

 

 

 

 

 

 

반응형

 

Cannot load Counter Name data because an invalid index '' was read from the registry. 오류가 발생한 경우 해결하는 방법에 대해 알아봅니다.

 

 

 

1. 현상

 

C# 프로그램을 실행하는데 "Cannot load Counter Name data because an invalid index '' was read from the registry."와 같은 에러가 발생하며 실행되지 않습니다.

 

 

 

2.  수정

 

cmd를 열어 다음 명령어를 수행합니다.

lodctr /r

 

해당 명령어를 수행했을 때 만약 다음과 같은 에러가 발생하면 다시 한번 수행해 줍니다.

ERROR: UNABLE TO REBUILD PERFORMANCE COUNTER SETTING FROM SYSTEM BACKUP STORE. ERROR CODE IS 2

 

다시 동일한 명령어를 수행하면 다음과 같이 정상적인 메시지가 출력됩니다.

 

프로그램을 다시 실행시키면 정상적으로 수행되는 것을 확인할 수 있습니다.

 

 

 

 

 

반응형

+ Recent posts